Helpex - Trao đổi & giúp đỡ Đăng nhập
482

Tôi có kịch bản kiểm tra giả sau đây:

function test(){
    var x = 0.1 * 0.2;
    document.write(x);
}
test();

Điều này sẽ in kết quả 0.020000000000000004trong khi nó sẽ chỉ in 0.02(nếu bạn sử dụng máy tính của bạn). Theo tôi hiểu điều này là do lỗi trong độ chính xác của phép nhân dấu phẩy động.

Có ai có một giải pháp tốt để trong trường hợp như vậy tôi nhận được kết quả chính xác 0.02? Tôi biết có những chức năng như toFixedhoặc làm tròn sẽ là một khả năng khác, nhưng tôi muốn thực sự có toàn bộ số được in mà không cần cắt và làm tròn. Chỉ muốn biết nếu một trong các bạn có một số giải pháp tốt đẹp, thanh lịch.

Tất nhiên, nếu không tôi sẽ làm tròn đến khoảng 10 chữ số.

482 hữu ích 5 bình luận 301k xem chia sẻ
34 trả lời 34
415

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 bạn đang làm.

  • Nếu bạn thực sự cần kết quả của mình để cộng chính xác, đặc biệt là khi bạn làm việc với tiền: hãy sử dụng kiểu dữ liệu thập phân đặc biệt.
  • Nếu bạn không muốn xem tất cả các vị trí thập phân thêm đó: chỉ cần định dạng kết quả của bạn được làm tròn thành 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ụ: 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ỉ cáu kỉnh 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 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 , điều này không thanh lịch chút nào, 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.

415 hữu ích 5 bình luận chia sẻ
104

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, nó sẽ làm tròn 0,999 ... lặp lại và chính xác để cộng / trừ một trên chữ số có nghĩa ít nhất.

Lưu ý: Khi xử lý các float 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 tại sao.

104 hữu ích 5 bình luận chia sẻ
62

Đối với các khuynh hướng toán học: http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

Cách tiếp cận được đề xuất là sử dụng các hệ số 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 0.1 * 0.2, hệ số hiệu chỉnh là 10và bạn đang thực hiện phép tính:

> 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

62 hữu ích 5 bình luận chia sẻ
39

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à điều đó NumberOfDecimals(X) + NumberOfDecimals(Y) = ExpectedNumberOfDecimals. Điều đó có nghĩa là nếu chúng ta có 0.123 * 0.12thì chúng ta biết rằng sẽ có 5 chữ số thập phân vì 0.123có 3 chữ số thập phân và 0.12có hai chữ số thập phân . Do đó, nếu JavaScript cho chúng ta một số như 0.014760000002chúng ta 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.

39 hữu ích 5 bình luận chia sẻ
24

Bạn đang tìm kiếm một sprintftriển khai cho JavaScript, để bạn có thể viết ra các float với các lỗi nhỏ trong đó (vì chúng được lưu trữ ở định dạng nhị phân) theo định dạng mà bạn mong đợi.

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

var yourString = sprintf("%.2f", yourNumber);

để in ra số của bạn dưới dạng nổi với hai chữ số 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 muốn bao gồm nhiều tệp hơn chỉ để làm tròn điểm nổi với độ chính xác nhất định.

24 hữu ích 4 bình luận chia sẻ
15

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 chính xác và không thập phân 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 ý. Các em gái đến bignumber.js.

Decimal.js

Một kiểu thập phân chính xác tùy ý cho JavaScript.

Đây là một số mã sử dụng BigNumber:

$(function(){

  
  var product = BigNumber(.1).times(.2);  
  $('#product').text(product);

  var sum = BigNumber(.1).plus(.2);  
  $('#sum').text(sum);


});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<!-- 1.4.1 is not the current version, but works for this example. -->
<script src="http://cdn.bootcss.com/bignumber.js/1.4.1/bignumber.min.js"></script>

.1 &times; .2 = <span id="product"></span><br>
.1 &plus; .2 = <span id="sum"></span><br>

15 hữu ích 1 bình luận chia sẻ
14
var times = function (a, b) {
    return Math.round((a * b) * 100)/100;
};

---hoặc là---

var fpFix = function (n) {
    return Math.round(n * 100)/100;
};

fpFix(0.1*0.2); // -> 0.02

---cũng thế---

var fpArithmetic = function (op, x, y) {
    var n = {
            '*': x * y,
            '-': x - y,
            '+': x + y,
            '/': x / y
        }[op];        

    return Math.round(n * 100)/100;
};

--- như trong ---

fpArithmetic('*', 0.1, 0.2);
// 0.02

fpArithmetic('+', 0.1, 0.2);
// 0.3

fpArithmetic('-', 0.1, 0.2);
// -0.1

fpArithmetic('/', 0.2, 0.1);
// 2
14 hữu ích 2 bình luận chia sẻ
14

Hàm này sẽ xác định độ chính xác cần thiết từ phép nhân hai số dấu phẩy động và trả về kết quả với độ chính xác phù hợp. Thanh lịch mặc dù nó không phải là.

function multFloats(a,b){
  var atens = Math.pow(10,String(a).length - String(a).indexOf('.') - 1), 
      btens = Math.pow(10,String(b).length - String(b).indexOf('.') - 1); 
  return (a * atens) * (b * btens) / (atens * btens); 
}
14 hữu ích 0 bình luận chia sẻ
10

Bạn chỉ cần quyết định xem bạn thực sự muốn bao nhiêu chữ số thập phân - không thể có bánh và ăn nó :-)

Lỗi số tích lũy với mỗi thao tác tiếp theo và nếu bạn không cắt bỏ sớm thì nó sẽ phát triển. Các thư viện số hiển thị kết quả trông đơn giản chỉ cần cắt bỏ 2 chữ số cuối cùng ở mỗi bước, các bộ đồng xử lý số cũng có chiều dài "bình thường" và "đầy đủ" vì cùng một lý do. Cuf-off có giá rẻ cho bộ xử lý nhưng rất đắt cho bạn trong tập lệnh (nhân và chia và sử dụng POV (...)). Lib toán học 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 toàn cầu với POV (10, n) - có nghĩa là bạn đã quyết định độ chính xác bạn cần :-) Sau đó, làm:

Math.floor(x*PREC_LIM)/PREC_LIM  // floor - you are cutting off, not rounding

Bạn cũng có thể tiếp tục làm toán và chỉ cắt bỏ ở cuối - giả sử rằng bạn chỉ hiển thị và không làm if-s với 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, cao hơn một chữ số thập phân so với sai số dự kiến ​​tối đa. Giả sử điểm cắt 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 vị trí cuối cùng (ít quan trọng thứ 3) và bạn có thể sử dụng nó để so sánh xem kết quả có nằm trong phạm vi eps dự kiến ​​hay không (0,02 -eps <0,1 * 0,2 <0,02 + eps).

10 hữu ích 3 bình luận chia sẻ
8

Hàm round () tại phpjs.org hoạt động độc đáo: http://phpjs.org/fifts/round

num = .01 + .06;  // yields 0.0699999999999
rnum = round(num,12); // yields 0.07
8 hữu ích 1 bình luận chia sẻ
7

Đáng ngạc nhiên, chức năng này chưa được đăng tải 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 Math.round (). Nó súc tích và cho phép thay đổi độ chính xác.

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

console.log (precisionRound (1234.5678, 1)); // sản lượng dự kiến: 1234.6

console.log (precisionRound (1234.5678, -1)); // sản lượng dự kiến: 1230

var inp = document.querySelectorAll('input');
var btn = document.querySelector('button');

btn.onclick = 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;
}
<input type='text' value='0.1'>
<input type='text' value='0.2'>
<button>Get Product</button>
<input type='text'>

7 hữu ích 1 bình luận chia sẻ
6

Kết quả bạn nhận được là chính xác và khá nhất quán trong các triển khai dấu phẩy động trong các ngôn ngữ, bộ xử lý và hệ điều hành khác nhau - điều duy nhất thay đổi là mức độ không chính xác khi số float thực sự là gấp đôi (hoặc cao hơn).

0,1 trong các dấu phẩy động nhị phân giống như 1/3 trong số thập phân (tức là 0,333333333333 ... mãi mãi), không có cách nào chính xác để xử lý nó.

Nếu bạn đang xử lý các float luôn mong đợi các lỗi làm tròn nhỏ, do đó, bạn cũng sẽ luôn phải làm tròn kết quả được hiển thị thành một cái gì đó hợp lý. Đổi lại, bạn nhận được số học rất nhanh và mạnh mẽ bởi vì tất cả các tính toán nằm trong hệ nhị phân nguyên gốc của bộ xử lý.

Hầu hết thời gian, giải pháp là không chuyển sang số học điểm cố định, chủ yếu là vì nó chậm hơn nhiều và 99% thời gian bạn không cần độ chính xác. Nếu bạn đang xử lý những thứ cần mức độ chính xác đó (ví dụ như giao dịch tài chính) thì Javascript có thể không phải là công cụ tốt nhất để sử dụng (vì bạn muốn thực thi các loại điểm cố định, ngôn ngữ tĩnh có lẽ tốt hơn ).

Bạn đang tìm kiếm giải pháp tao nhã thì tôi e rằng đây là: phao nhanh nhưng có lỗi làm tròn nhỏ - luôn làm tròn thành thứ gì đó hợp lý khi hiển thị kết quả của chúng.

6 hữu ích 0 bình luận chia sẻ
6

Để tránh điều này, bạn nên làm việc với các giá trị nguyên thay vì các dấu phẩy động. Vì vậy, khi bạn muốn có 2 vị trí chính xác làm việc với các giá trị * 100, đối với 3 vị trí sử dụng 1000. Khi hiển thị, bạn sử dụng một bộ định dạng để đặt vào dấu phân cách.

Nhiều hệ thống bỏ qua làm việc với số thập phân theo cách này. Đó là lý do tại sao nhiều hệ thống hoạt động với xu (dưới dạng số nguyên) thay vì đô la / euro (dưới dạng dấu phẩy động).

6 hữu ích 0 bình luận chia sẻ
5

Bạn có thể sử dụng parseFloat()toFixed()nếu bạn muốn bỏ qua vấn đề này cho một thao tác nhỏ:

a = 0.1;
b = 0.2;

a + b = 0.30000000000000004;

c = parseFloat((a+b).toFixed(2));

c = 0.3;

a = 0.3;
b = 0.2;

a - b = 0.09999999999999998;

c = parseFloat((a-b).toFixed(2));

c = 0.1;
5 hữu ích 0 bình luận chia sẻ
5

Vấn đề

Điểm nổi không thể lưu trữ chính xác tất cả các giá trị thập phân. Vì vậy, khi sử dụng các định dạng dấu phẩy động sẽ luôn có lỗi làm tròn trên các giá trị đầu vào. Các lỗi về đầu vào tất nhiên dẫn đến lỗi trên đầu ra. Trong trường hợp hàm hoặc toán tử rời rạc, có thể có sự khác biệt lớn về đầu ra xung quanh điểm mà hàm hoặc toán tử rời rạc.

Đầu vào và đầu ra cho các giá trị dấu phẩy động

Vì vậy, khi sử dụng các biến dấu phẩy động, bạn nên luôn luôn nhận thức được điều này. Và bất kỳ đầu ra nào bạn muốn từ một phép tính với các dấu phẩy động phải luôn được định dạng / điều hòa trước khi hiển thị với ý nghĩ này.
Khi chỉ sử dụng các hàm và toán tử liên tục, làm tròn đến độ chính xác mong muốn thường sẽ làm (không cắt bớt). Các tính năng định dạng tiêu chuẩn được sử dụng để chuyển đổi float thành chuỗi thường sẽ làm điều này cho bạn.
Bởi vì làm tròn thêm một lỗi có thể gây ra tổng sai số lớn hơn một nửa độ chính xác mong muốn, đầu ra phải được sửa dựa trên độ chính xác dự kiến ​​của đầu vào và độ chính xác đầu ra mong muốn. Bạn nên

  • Làm tròn đầu vào với độ chính xác dự kiến ​​hoặc đảm bảo không có giá trị nào có thể được nhập với độ chính xác cao hơn.
  • Thêm một giá trị nhỏ vào các đầu ra trước khi làm tròn / định dạng chúng nhỏ hơn hoặc bằng 1/4 độ chính xác mong muốn và lớn hơn sai số tối đa dự kiến ​​gây ra bởi lỗi làm tròn trên đầu vào và trong khi tính toán. Nếu điều đó là không thể, sự kết hợp độ chính xác của kiểu dữ liệu được sử dụng sẽ không đủ để cung cấp độ chính xác đầu ra mong muốn cho tính toán của bạn.

Hai điều này thường không được thực hiện và trong hầu hết các trường hợp, sự khác biệt gây ra bởi việc không thực hiện chúng quá nhỏ không quan trọng đối với hầu hết người dùng, nhưng tôi đã có một dự án mà người dùng không chấp nhận đầu ra mà không cần chỉnh sửa.

Các hàm hoặc toán tử rời rạc (như modula)

Khi các toán tử hoặc hàm rời rạc có liên quan, có thể cần phải hiệu chỉnh thêm để đảm bảo đầu ra như mong đợi. Làm tròn và thêm các hiệu chỉnh nhỏ trước khi làm tròn không thể giải quyết vấn đề.
Một kiểm tra / hiệu chỉnh đặc biệt về kết quả tính toán trung gian, ngay sau khi áp dụng hàm hoặc toán tử rời rạc có thể được yêu cầu. Đối với một trường hợp cụ thể (toán tử modula), hãy xem câu trả lời của tôi về câu hỏi: Tại sao toán tử mô đun trả về số phân số trong javascript?

Tốt hơn nên tránh có vấn đề

Việc tránh các vấn đề này thường hiệu quả hơn bằng cách sử dụng các loại dữ liệu (định dạng số nguyên hoặc điểm cố định) cho các phép tính như thế này có thể lưu trữ đầu vào dự kiến ​​mà không làm tròn lỗi. Một ví dụ về điều đó là bạn không bao giờ nên sử dụng các giá trị dấu phẩy động để tính toán tài chính.

5 hữu ích 0 bình luận chia sẻ
4

0,6 * 3 thật tuyệt vời!)) Đối với tôi điều này hoạt động tốt:

function dec( num )
{
    var p = 100;
    return Math.round( num * p ) / p;
}

Rất rất đơn giản))

4 hữu ích 3 bình luận chia sẻ
3

Có một cái nhìn vào số học điểm cố định . Nó có thể sẽ giải quyết vấn đề của bạn, nếu phạm vi số bạn muốn hoạt động là nhỏ (ví dụ: tiền tệ). Tôi sẽ làm tròn nó thành một vài giá trị thập phân, đó là giải pháp đơn giản nhất.

3 hữu ích 2 bình luận chia sẻ
3

Hãy thử thư viện số học chiliadic của tôi, mà bạn có thể thấy ở đây . Nếu bạn muốn có một phiên bản mới hơn, tôi có thể lấy cho bạn một phiên bản.

3 hữu ích 0 bình luận chia sẻ
3

Bạn không thể biểu diễn hầu hết các phân số thập phân chính xác bằng các loại dấu phẩy động nhị phân (đó là những gì ECMAScript sử dụng để biểu thị các giá trị dấu phẩy động). Vì vậy, không có một giải pháp tao nhã trừ khi bạn sử dụng các loại số học chính xác tùy ý hoặc một loại dấu phẩy động dựa trên số thập phân. Ví dụ: ứng dụng Máy tính đi kèm với Windows hiện sử dụng số học chính xác tùy ý để giải quyết vấn đề này .

3 hữu ích 0 bình luận chia sẻ
3

Làm thế nào để đối phó với độ chính xác số dấu phẩy động trong JavaScript?

    You can use library https://github.com/MikeMcl/decimal.js/. 
    it will   help  lot to give proper solution. 
    javascript console output 95 *722228.630 /100 = 686117.1984999999
    decimal library implementation 
    var firstNumber = new Decimal(95);
    var secondNumber = new Decimal(722228.630);
    var thirdNumber = new Decimal(100);
    var partialOutput = firstNumber.times(secondNumber);
    console.log(partialOutput);
    var output = new Decimal(partialOutput).div(thirdNumber);
    alert(output.valueOf());
    console.log(output.valueOf())== 686117.1985
3 hữu ích 0 bình luận chia sẻ
2

Tôi gặp vấn đề về làm tròn khó chịu với mod 3. Đôi khi, khi tôi nhận được 0, tôi sẽ nhận được .000 ... 01. Điều đó đủ dễ để xử lý, chỉ cần kiểm tra <= .01. Nhưng sau đó đôi khi tôi sẽ nhận được 2.99999999999998. NGOÀI RA!

BigNumbers đã giải quyết vấn đề, nhưng đã giới thiệu một vấn đề khác, hơi mỉa mai. Khi thử tải 8,5 vào BigNumbers, tôi được thông báo rằng nó thực sự là 8.4999 và có hơn 15 chữ số có nghĩa. Điều này có nghĩa là BigNumbers không thể chấp nhận nó (tôi tin rằng tôi đã đề cập vấn đề này có phần mỉa mai).

Giải pháp đơn giản cho vấn đề mỉa mai:

x = Math.round(x*100);
// I only need 2 decimal places, if i needed 3 I would use 1,000, etc.
x = x / 100;
xB = new BigNumber(x);
2 hữu ích 0 bình luận chia sẻ
2

Lưu ý rằng đối với mục đích sử dụng chung, hành vi này có thể được chấp nhận.
Vấn đề phát sinh khi so sánh các giá trị dấu phẩy động đó để xác định một hành động thích hợp.
Với sự ra đời của ES6, một hằng số mới Number.EPSILONđược xác định để xác định tỷ lệ lỗi chấp nhận được:
Vì vậy, thay vì thực hiện so sánh như thế này

0.1 + 0.2 === 0.3 // which returns false

bạn có thể định nghĩa một chức năng so sánh tùy chỉnh, như thế này:

function epsEqu(x, y) {
    return Math.abs(x - y) < Number.EPSILON;
}
console.log(epsEqu(0.1+0.2, 0.3)); // true

Nguồn: http://2ality.com/2015/04/numbers-math-es6.html#numberepsilon

2 hữu ích 1 bình luận chia sẻ
1

Sử dụng

var x = 0.1*0.2;
 x =Math.round(x*Math.pow(10,2))/Math.pow(10,2);
1 hữu ích 2 bình luận chia sẻ
1

không thanh lịch nhưng thực hiện công việc (loại bỏ các số 0 ở cuối)

var num = 0.1*0.2;
alert(parseFloat(num.toFixed(10))); // shows 0.02
1 hữu ích 1 bình luận chia sẻ
1

Bạn đã đúng, lý do cho điều đó là độ chính xác hạn chế của số dấu phẩy động. Lưu trữ số hữu tỷ của bạn dưới dạng chia hai số nguyên và trong hầu hết các tình huống, bạn sẽ có thể lưu trữ số mà không bị mất độ chính xác. Khi nói đến in, bạn có thể muốn hiển thị kết quả dưới dạng phân số. Với đại diện tôi đề xuất, nó trở nên tầm thường.

Tất nhiên điều đó sẽ không giúp được nhiều với những con số vô lý. Nhưng bạn có thể muốn tối ưu hóa các tính toán của mình theo cách chúng sẽ gây ra ít vấn đề nhất (ví dụ: phát hiện các tình huống như thế nào sqrt(3)^2).

1 hữu ích 1 bình luận chia sẻ
1

Sử dụng Số (1.234443) .toFixed (2); nó sẽ in 1,23

function test(){
    var x = 0.1 * 0.2;
    document.write(Number(x).toFixed(2));
}
test();
1 hữu ích 0 bình luận chia sẻ
0

Điều này làm việc cho tôi:

function round_up( value, precision ) { 
    var pow = Math.pow ( 10, precision ); 
    return ( Math.ceil ( pow * value ) + Math.ceil ( pow * value - Math.ceil ( pow * value ) ) ) / pow; 
}

round_up(341.536, 2); // 341.54
0 hữu ích 1 bình luận chia sẻ
0

Đầu ra sử dụng chức năng sau:

var toFixedCurrency = function(num){
    var num = (num).toString();
    var one = new RegExp(/\.\d{1}$/).test(num);
    var two = new RegExp(/\.\d{2,}/).test(num);
    var result = null;

    if(one){ result = num.replace(/\.(\d{1})$/, '.$10');
    } else if(two){ result = num.replace(/\.(\d{2})\d*/, '.$1');
    } else { result = num*100; }

    return result;
}

function test(){
    var x = 0.1 * 0.2;
    document.write(toFixedCurrency(x));
}

test();

Hãy chú ý đến đầu ra toFixedCurrency(x).

0 hữu ích 0 bình luận chia sẻ
0

trong khi thêm hai giá trị float, nó không bao giờ đưa ra các giá trị chính xác, vì vậy chúng ta cần cố định giá trị này với một số nhất định sẽ giúp chúng ta so sánh.

console.log ((parseFloat (0.1) + parseFloat (0.2)). toFixed (1) == parseFloat (0.3) .toFixed (1));
0 hữu ích 0 bình luận chia sẻ
0

Tôi không giỏi lập trình lắm, nhưng thực sự hứng thú với chủ đề này nên tôi đã cố gắng hiểu cách giải quyết mà không cần sử dụng bất kỳ thư viện hay tập lệnh nào

Tôi đã viết cái này trên Scratchpad

var toAlgebraic = function(f1, f2) {
    let f1_base = Math.pow(10, f1.split('.')[1].length);
    let f2_base = Math.pow(10, f2.split('.')[1].length);
    f1 = parseInt(f1.replace('.', ''));
    f2 = parseInt(f2.replace('.', ''));

    let dif, base;
    if (f1_base > f2_base) {
        dif = f1_base / f2_base;
        base = f1_base;
        f2 = f2 * dif;
    } else {
        dif = f2_base / f1_base;
        base = f2_base;
        f1 = f1 * dif;
    }

    return (f1 * f2) / base;
};

console.log(0.1 * 0.2);
console.log(toAlgebraic("0.1", "0.2"));

bạn có thể cần cấu trúc lại mã này, vì tôi không giỏi lập trình :)

0 hữu ích 0 bình luận chia sẻ
loading
Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ javascript floating-point , hoặc hỏi câu hỏi của bạn.

Có thể bạn quan tâm

loading