最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Math.round vs. math.ceil yields unexpected results - Stack Overflow

programmeradmin1浏览0评论

The user may input a value or a simple expression as a division. The output should be a value to 2 decimal places. e.g.

8.50 should yield 8.50
4/2 should yield 2.00

But if the input is a division resulting in a fractional value, the output should be rounded up. e.g.

500/3 should yield 166.67

Using the following calculation:

var fieldVal = 500/3;
fieldVal = Math.ceil(fieldVal * 100) / 100;
fieldVal; // yields 166.67 - good

But if fieldVal = 8.88 the calc yields 8.89

If I use:

var fieldVal = 8.88;
fieldVal = Math.round(fieldVal * 100) / 100;
fieldVal; // yields 8.88 - good

But:

var fieldVal =  500/6.95;
fieldVal = Math.round(fieldVal * 100) / 100;
fieldVal; // yields 71.94

But I want 71.95 since 500/6.95 yields 71.942... (because I want to round up in such a case)

I'm at a loss. What is the solution here?

The user may input a value or a simple expression as a division. The output should be a value to 2 decimal places. e.g.

8.50 should yield 8.50
4/2 should yield 2.00

But if the input is a division resulting in a fractional value, the output should be rounded up. e.g.

500/3 should yield 166.67

Using the following calculation:

var fieldVal = 500/3;
fieldVal = Math.ceil(fieldVal * 100) / 100;
fieldVal; // yields 166.67 - good

But if fieldVal = 8.88 the calc yields 8.89

If I use:

var fieldVal = 8.88;
fieldVal = Math.round(fieldVal * 100) / 100;
fieldVal; // yields 8.88 - good

But:

var fieldVal =  500/6.95;
fieldVal = Math.round(fieldVal * 100) / 100;
fieldVal; // yields 71.94

But I want 71.95 since 500/6.95 yields 71.942... (because I want to round up in such a case)

I'm at a loss. What is the solution here?

Share Improve this question edited Dec 29, 2015 at 1:41 Ultimater 4,7482 gold badges31 silver badges43 bronze badges asked Dec 29, 2015 at 1:04 AlphaBaseAlphaBase 751 silver badge7 bronze badges 9
  • 6 why do you call fieldVal = eval(fieldVal); ? it's useless here. – anotherdev Commented Dec 29, 2015 at 1:06
  • what @PierreEmmanuelLallemant said. AND eval is evil! – nonchip Commented Dec 29, 2015 at 1:07
  • 2 also if you want to round up from 71.942 to 7.95 you're not going to make that work in ANY numerical system ;) – nonchip Commented Dec 29, 2015 at 1:08
  • 1 eval is fantastically useful, but should be used carefully.. – Xotic750 Commented Dec 29, 2015 at 1:09
  • 1 I think the question is a bit unclear, and had to be read a few times to understand what the actual problem is. As I see it, your question is how to make a universal function using either .ceil or .round that works with all possible values. – Claies Commented Dec 29, 2015 at 1:29
 |  Show 4 more ments

3 Answers 3

Reset to default 5

You can't do it in a simple way.

The problem is that the puter stores numbers in base 2, and has a finite precision. Then, your 8.88 bees

8.88000000000000078159700933611020445823669433593750

According to your rules, it is rounded up to 8.89.

A solution could be multiplying your quantities by 100 (in the source code, not using JS), and divide them by 100 at the end.

var fieldVal100 = 888; // 8.88 * 100
fieldVal100 = Math.ceil(fieldVal100);
var fieldVal = fieldVal100 / 100; // 8.88

var fieldVal100 = 50000/3; // 500/3 * 100
fieldVal100 = Math.ceil(fieldVal100);
var fieldVal = fieldVal100 / 100; // 166.67

var fieldVal100 = 50000/6.95; // 500/6.95 * 100
fieldVal100 = Math.ceil(fieldVal100);
var fieldVal = fieldVal100 / 100; // 71.95

Another solution would be storing the numbers as strings instead of numbers, and use some library which operates those strings in base 10.

If you want to round up use ceil() and not round():

fieldVal = Math.ceil(fieldVal * 100) / 100;

If you round 7194.2 you will get 7194 and not 7195, hence leading to 71.94.

The reason why 8.88 * 100 is going to 8.89 is because the way puters store decimal numbers. Because they cannot represent all possible decimals they are approximated to a degree. So 8.88 * 100 = 888.0000000000001, which using ceil leads to 889.

the basic difference...

The Math.floor() returns or round off always down i.e. Math.floor(3.8) will give the result as 3.

The Math.round returns or round off always to the nearest integer i.e. Math.round(3.8) yields 4 as the nearest integer possible.

The Math.ceil() returns or round off always upwards i.e. Math.ceil(3.8) yields 4 as nearest upward integer.

发布评论

评论列表(0)

  1. 暂无评论