Hướng dẫn javascript check float precision - javascript kiểm tra độ chính xác float

Từ hướng dẫn điểm nổi:

Tôi có thể làm gì để tránh vấn đề này?

Điều đó phụ thuộc vào loại tính toán mà bạn đang làm.

  • Nếu bạn thực sự cần kết quả của mình để thêm chính xác, đặc biệt là khi bạn làm việc với tiền: sử dụng kiểu dữ liệu thập phân đặc biệt.
  • Nếu bạn chỉ không muốn xem tất cả những vị trí thập phân bổ sung đó: chỉ cần định dạng kết quả của bạn được làm tròn đến một số vị trí thập phân cố định khi hiển thị nó.
  • Nếu bạn không có kiểu dữ liệu thập phân có sẵn, một giải pháp thay thế là làm việc với các số nguyên, ví dụ: Làm tính toán tiền hoàn toàn bằng xu. Nhưng đây là công việc nhiều hơn và có một số nhược điểm.

Lưu ý rằng điểm đầu tiên chỉ áp dụng nếu bạn thực sự cần hành vi thập phân chính xác cụ thể. Hầu hết mọi người không cần điều đó, họ chỉ bị kích thích rằng các chương trình của họ không hoạt động chính xác với các số như 1/10 mà không nhận ra rằng họ thậm chí sẽ không chớp mắt với cùng một lỗi nếu nó xảy ra với 1/3.

Nếu điểm đầu tiên thực sự áp dụng cho bạn, hãy sử dụng BigDecimal cho JavaScript, hoàn toàn không thanh lịch, nhưng thực sự giải quyết vấn đề thay vì cung cấp một cách giải quyết không hoàn hảo.

Mike

22.6K14 Huy hiệu vàng73 Huy hiệu bạc86 Huy hiệu đồng14 gold badges73 silver badges86 bronze badges

Đã trả lời ngày 9 tháng 8 năm 2010 lúc 12:30Aug 9, 2010 at 12:30

Michael Borgwardtmichael BorgwardtMichael Borgwardt

339K77 Huy hiệu vàng476 Huy hiệu bạc711 Huy hiệu đồng77 gold badges476 silver badges711 bronze badges

21

Tôi thích giải pháp của Pedro Ladaria và sử dụng một cái gì đó tương tự.

function strip[number] {
    return [parseFloat[number].toPrecision[12]];
}

Không giống như giải pháp Pedros, điều này sẽ làm tròn 0,999 ... lặp lại và chính xác với cộng/trừ một trên chữ số ít có ý nghĩa nhất.

Lưu ý: Khi xử lý các phao 32 hoặc 64 bit, bạn nên sử dụng TopRecision [7] và TopRecision [15] để có kết quả tốt nhất. Xem câu hỏi này để biết thông tin về lý do tại sao.

Đã trả lời ngày 4 tháng 9 năm 2010 lúc 23:00Sep 4, 2010 at 23:00

linux_mikelinux_mikelinux_mike

Huy hiệu vàng 2.4031 Huy hiệu bạc3 Huy hiệu đồng 31 gold badge16 silver badges3 bronze badges

12

Đối với nghiêng về mặt toán học: //docs.oracle.com/cd/e19957-01/806-3568/ncg_goldberg.html

Cách tiếp cận được khuyến nghị là sử dụng các yếu tố hiệu chỉnh [nhân với công suất phù hợp là 10 để số học xảy ra giữa các số nguyên]. Ví dụ, trong trường hợp của

> Math.m[0.1, 0.2]
0.02
9, hệ số hiệu chỉnh là
function precisionRound[number, precision] {
    var factor = Math.pow[10, precision];
    return Math.round[number * factor] / factor;
}

console.log[precisionRound[1234.5678, 1]];
// expected output: 1234.6

console.log[precisionRound[1234.5678, -1]];
// expected output: 1230
0 và bạn đang thực hiện tính toán:

> var x = 0.1
> var y = 0.2
> var cf = 10
> x * y
0.020000000000000004
> [x * cf] * [y * cf] / [cf * cf]
0.02

Một giải pháp [rất nhanh] trông giống như:

var _cf = [function[] {
  function _shift[x] {
    var parts = x.toString[].split['.'];
    return [parts.length < 2] ? 1 : Math.pow[10, parts[1].length];
  }
  return function[] { 
    return Array.prototype.reduce.call[arguments, function [prev, next] { return prev === undefined || next === undefined ? undefined : Math.max[prev, _shift [next]]; }, -Infinity];
  };
}][];

Math.a = function [] {
  var f = _cf.apply[null, arguments]; if[f === undefined] return undefined;
  function cb[x, y, i, o] { return x + f * y; }
  return Array.prototype.reduce.call[arguments, cb, 0] / f;
};

Math.s = function [l,r] { var f = _cf[l,r]; return [l * f - r * f] / f; };

Math.m = function [] {
  var f = _cf.apply[null, arguments];
  function cb[x, y, i, o] { return [x*f] * [y*f] / [f * f]; }
  return Array.prototype.reduce.call[arguments, cb, 1];
};

Math.d = function [l,r] { var f = _cf[l,r]; return [l * f] / [r * f]; };

Trong trường hợp này:

> Math.m[0.1, 0.2]
0.02

Tôi chắc chắn khuyên bạn nên sử dụng một thư viện được thử nghiệm như sinfuljs

Đã trả lời ngày 20 tháng 9 năm 2013 lúc 2:55Sep 20, 2013 at 2:55

SheetJSsheetjsSheetJS

21.9K12 Huy hiệu vàng63 Huy hiệu bạc75 Huy hiệu Đồng12 gold badges63 silver badges75 bronze badges

8

Bạn chỉ thực hiện phép nhân? Nếu vậy thì bạn có thể sử dụng lợi thế của mình một bí mật gọn gàng về số học thập phân. Đó là

function precisionRound[number, precision] {
    var factor = Math.pow[10, precision];
    return Math.round[number * factor] / factor;
}

console.log[precisionRound[1234.5678, 1]];
// expected output: 1234.6

console.log[precisionRound[1234.5678, -1]];
// expected output: 1230
1. Điều đó có nghĩa là nếu chúng ta có
function precisionRound[number, precision] {
    var factor = Math.pow[10, precision];
    return Math.round[number * factor] / factor;
}

console.log[precisionRound[1234.5678, 1]];
// expected output: 1234.6

console.log[precisionRound[1234.5678, -1]];
// expected output: 1230
2 thì chúng ta biết rằng sẽ có 5 vị trí thập phân vì
function precisionRound[number, precision] {
    var factor = Math.pow[10, precision];
    return Math.round[number * factor] / factor;
}

console.log[precisionRound[1234.5678, 1]];
// expected output: 1234.6

console.log[precisionRound[1234.5678, -1]];
// expected output: 1230
3 có 3 số thập phân và
function precisionRound[number, precision] {
    var factor = Math.pow[10, precision];
    return Math.round[number * factor] / factor;
}

console.log[precisionRound[1234.5678, 1]];
// expected output: 1234.6

console.log[precisionRound[1234.5678, -1]];
// expected output: 1230
4 có hai vị trí. Do đó, nếu JavaScript cho chúng tôi một số như
function precisionRound[number, precision] {
    var factor = Math.pow[10, precision];
    return Math.round[number * factor] / factor;
}

console.log[precisionRound[1234.5678, 1]];
// expected output: 1234.6

console.log[precisionRound[1234.5678, -1]];
// expected output: 1230
5, chúng tôi có thể làm tròn một cách an toàn đến vị trí thập phân thứ 5 mà không sợ mất độ chính xác.

Đã trả lời ngày 11 tháng 8 năm 2010 lúc 14:33Aug 11, 2010 at 14:33

Nate Zauggnate ZauggNate Zaugg

4.1622 Huy hiệu vàng36 Huy hiệu bạc53 Huy hiệu Đồng2 gold badges36 silver badges53 bronze badges

5

Đáng ngạc nhiên, chức năng này chưa được đăng mặc dù những người khác có các biến thể tương tự của nó. Đó là từ các tài liệu web MDN cho

function precisionRound[number, precision] {
    var factor = Math.pow[10, precision];
    return Math.round[number * factor] / factor;
}

console.log[precisionRound[1234.5678, 1]];
// expected output: 1234.6

console.log[precisionRound[1234.5678, -1]];
// expected output: 1230
6. Nó súc tích và cho phép độ chính xác khác nhau.

function precisionRound[number, precision] {
    var factor = Math.pow[10, precision];
    return Math.round[number * factor] / factor;
}

console.log[precisionRound[1234.5678, 1]];
// expected output: 1234.6

console.log[precisionRound[1234.5678, -1]];
// expected output: 1230

var inp = document.querySelectorAll['input'];
var btn = document.querySelector['button'];

btn. title = function[]{
  inp[2].value = precisionRound[ parseFloat[inp[0].value] * parseFloat[inp[1].value] , 5 ];
};

//MDN function
function precisionRound[number, precision] {
  var factor = Math.pow[10, precision];
  return Math.round[number * factor] / factor;
}
button{
display: block;
}


Get Product

Cập nhật: tháng 8/20/2019

Chỉ nhận thấy lỗi này. Tôi tin rằng đó là do lỗi chính xác điểm nổi với

function precisionRound[number, precision] {
    var factor = Math.pow[10, precision];
    return Math.round[number * factor] / factor;
}

console.log[precisionRound[1234.5678, 1]];
// expected output: 1234.6

console.log[precisionRound[1234.5678, -1]];
// expected output: 1230
6.

precisionRound[1.005, 2] // produces 1, incorrect, should be 1.01

Những điều kiện này hoạt động chính xác:

precisionRound[0.005, 2] // produces 0.01
precisionRound[1.0005, 3] // produces 1.001
precisionRound[1234.5, 0] // produces 1235
precisionRound[1234.5, -1] // produces 1230

Fix:

> var x = 0.1
> var y = 0.2
> var cf = 10
> x * y
0.020000000000000004
> [x * cf] * [y * cf] / [cf * cf]
0.02
0

Điều này chỉ thêm một chữ số ở bên phải khi làm tròn số thập phân. MDN đã cập nhật trang

function precisionRound[number, precision] {
    var factor = Math.pow[10, precision];
    return Math.round[number * factor] / factor;
}

console.log[precisionRound[1234.5678, 1]];
// expected output: 1234.6

console.log[precisionRound[1234.5678, -1]];
// expected output: 1230
6 để có thể ai đó có thể cung cấp một giải pháp tốt hơn.

Zhulien

4.6603 Huy hiệu vàng17 Huy hiệu bạc33 Huy hiệu đồng3 gold badges17 silver badges33 bronze badges

Đã trả lời ngày 9 tháng 4 năm 2018 lúc 9:30Apr 9, 2018 at 9:30

4

Tôi đang tìm Bignumber.js đáp ứng nhu cầu của tôi.

Một thư viện JavaScript cho số học thập phân và không phân biệt chính xác tùy ý.

Nó có tài liệu tốt và tác giả rất siêng năng trả lời phản hồi.

Cùng một tác giả có 2 thư viện tương tự khác:

Big.js

Một thư viện JavaScript nhỏ, nhanh cho số học thập phân chính xác tùy ý. Em gái của Bignumber.js.

và thập phân.js

Một loại thập phân có độ chính xác tùy ý cho JavaScript.

Dưới đây là một số mã sử dụng Bignumber:

> var x = 0.1
> var y = 0.2
> var cf = 10
> x * y
0.020000000000000004
> [x * cf] * [y * cf] / [cf * cf]
0.02
1
> var x = 0.1
> var y = 0.2
> var cf = 10
> x * y
0.020000000000000004
> [x * cf] * [y * cf] / [cf * cf]
0.02
2

Cerbrus

68.2K18 Huy hiệu vàng131 Huy hiệu bạc144 Huy hiệu đồng18 gold badges131 silver badges144 bronze badges

Đã trả lời ngày 2 tháng 12 năm 2014 lúc 14:35Dec 2, 2014 at 14:35

Ronnie Overbyronnie OverbyRonnie Overby

44.2K73 Huy hiệu vàng265 Huy hiệu bạc345 Huy hiệu đồng73 gold badges265 silver badges345 bronze badges

2

Bạn đang tìm kiếm một triển khai

function precisionRound[number, precision] {
    var factor = Math.pow[10, precision];
    return Math.round[number * factor] / factor;
}

console.log[precisionRound[1234.5678, 1]];
// expected output: 1234.6

console.log[precisionRound[1234.5678, -1]];
// expected output: 1230
9 cho JavaScript, để bạn có thể viết ra phao với các lỗi nhỏ trong đó [vì chúng được lưu trữ ở định dạng nhị phân] ở định dạng mà bạn mong đợi.

Hãy thử javascript-sprintf, bạn sẽ gọi nó như thế này:

> var x = 0.1
> var y = 0.2
> var cf = 10
> x * y
0.020000000000000004
> [x * cf] * [y * cf] / [cf * cf]
0.02
3

Để in ra số của bạn dưới dạng phao với hai vị trí thập phân.

Bạn cũng có thể sử dụng number.tofixed [] cho mục đích hiển thị, nếu bạn không chỉ bao gồm nhiều tệp hơn chỉ để làm tròn điểm nổi đến một độ chính xác nhất định.

erik258

12.9k2 Huy hiệu vàng26 Huy hiệu bạc29 Huy hiệu đồng2 gold badges26 silver badges29 bronze badges

Đã trả lời ngày 6 tháng 8 năm 2010 lúc 8:38Aug 6, 2010 at 8:38

DouglasdouglasDouglas

Phim huy hiệu vàng 35,8k88 gold badges73 silver badges89 bronze badges

3

> var x = 0.1
> var y = 0.2
> var cf = 10
> x * y
0.020000000000000004
> [x * cf] * [y * cf] / [cf * cf]
0.02
4

---or---

> var x = 0.1
> var y = 0.2
> var cf = 10
> x * y
0.020000000000000004
> [x * cf] * [y * cf] / [cf * cf]
0.02
5

---also---

> var x = 0.1
> var y = 0.2
> var cf = 10
> x * y
0.020000000000000004
> [x * cf] * [y * cf] / [cf * cf]
0.02
6

--- như trong ---

> var x = 0.1
> var y = 0.2
> var cf = 10
> x * y
0.020000000000000004
> [x * cf] * [y * cf] / [cf * cf]
0.02
7

Đã trả lời ngày 8 tháng 8 năm 2010 lúc 3:16Aug 8, 2010 at 3:16

Shawndumasthawndumasshawndumas

1.37314 Huy hiệu bạc17 Huy hiệu đồng14 silver badges17 bronze badges

2

Bạn có thể sử dụng

var inp = document.querySelectorAll['input'];
var btn = document.querySelector['button'];

btn. title = function[]{
  inp[2].value = precisionRound[ parseFloat[inp[0].value] * parseFloat[inp[1].value] , 5 ];
};

//MDN function
function precisionRound[number, precision] {
  var factor = Math.pow[10, precision];
  return Math.round[number * factor] / factor;
}
0 và
var inp = document.querySelectorAll['input'];
var btn = document.querySelector['button'];

btn. title = function[]{
  inp[2].value = precisionRound[ parseFloat[inp[0].value] * parseFloat[inp[1].value] , 5 ];
};

//MDN function
function precisionRound[number, precision] {
  var factor = Math.pow[10, precision];
  return Math.round[number * factor] / factor;
}
1 nếu bạn muốn bỏ qua vấn đề này cho một hoạt động nhỏ:

> var x = 0.1
> var y = 0.2
> var cf = 10
> x * y
0.020000000000000004
> [x * cf] * [y * cf] / [cf * cf]
0.02
8

gion_13

40.8k10 Huy hiệu vàng97 Huy hiệu bạc107 Huy hiệu đồng10 gold badges97 silver badges107 bronze badges

Đã trả lời ngày 4 tháng 3 năm 2015 lúc 13:49Mar 4, 2015 at 13:49

SoftwareddysoftwareddySoftwareddy

7211 Huy hiệu vàng7 Huy hiệu bạc9 Huy hiệu đồng1 gold badge7 silver badges9 bronze badges

Bạn chỉ cần phải quyết định về số lượng chữ số thập phân bạn thực sự muốn - không thể ăn và ăn nó :-]

Lỗi số tích lũy với mọi hoạt động tiếp theo và nếu bạn không cắt giảm sớm thì nó sẽ phát triển. Các thư viện số trình bày kết quả trông sạch sẽ chỉ đơn giản là cắt 2 chữ số cuối cùng ở mỗi bước, các đồng xử lý số cũng có độ dài "bình thường" và "đầy đủ" vì cùng một lý do. CUF-off là giá rẻ cho một bộ xử lý nhưng rất tốn kém cho bạn trong một tập lệnh [nhân và chia và sử dụng POV [...]]. Lib toán tốt sẽ cung cấp sàn [x, n] để thực hiện việc cắt giảm cho bạn.

Vì vậy, ít nhất bạn nên tạo VAR/hằng số toàn cầu với POV [10, n] - có nghĩa là bạn đã quyết định về độ chính xác mà bạn cần :-] Sau đó làm:

> var x = 0.1
> var y = 0.2
> var cf = 10
> x * y
0.020000000000000004
> [x * cf] * [y * cf] / [cf * cf]
0.02
9

Bạn cũng có thể tiếp tục làm toán và chỉ bị cắt ở cuối-giả sử rằng bạn chỉ hiển thị và không làm IF-S có kết quả. Nếu bạn có thể làm điều đó, thì .tofixed [...] có thể hiệu quả hơn.

Nếu bạn đang thực hiện if-s/so sánh và không muốn cắt thì bạn cũng cần một hằng số nhỏ, thường được gọi là EPS, đó là một vị trí thập phân cao hơn lỗi tối đa dự kiến. Giả sử rằng việc giới hạn của bạn là hai số thập phân cuối cùng -sau đó EPS của bạn có 1 ở vị trí thứ 3 so với lần cuối [ít thứ 3 có ý nghĩa nhất] và bạn có thể sử dụng nó để so sánh liệu kết quả có nằm trong phạm vi EPS dự kiến ​​hay không [0,02 -eps

Bài Viết Liên Quan

Chủ Đề