如何在不向上或向下舍入的情况下获得精确的数字[重复]

Posted

技术标签:

【中文标题】如何在不向上或向下舍入的情况下获得精确的数字[重复]【英文标题】:How to get numbers with precision without round up or round down [duplicate] 【发布时间】:2014-05-26 02:34:36 【问题描述】:

我试图得到一个精确到小数点后 2 位的数字,例如,如果我有数字,这就是我想要的:

3.456 it must returns me 3.45
3.467 = 3.46
3.435 = 3.43
3.422 = 3.42

我不想四舍五入或其他任何只是为了得到我在 2 之后看到的数字。

谢谢


好的,答案就在这里

var a = 5.469923;
var truncated = Math.floor(a * 100) / 100; // = 5.46

感谢大家的帮助。

【问题讨论】:

了解 ParseFloat 函数 那是精度的对立面 @juvian parseFloat 有什么帮助? 尽管有标题,但您要求四舍五入。 parseFloat 对这个@bto.rdz 没有帮助,你能帮忙吗? 【参考方案1】:

假设为正数:

代码:

function roundDown(num,dec) 
    return Math.floor(num*Math.pow(10,dec))/Math.pow(10,dec);

测试:

function test(num, expected) 
    var val = roundDown(num,2);
    var pass = val === expected;
    var result =  pass ? "PASS" : "FAIL";
    var color = pass ? "GREEN" : "RED";
    console.log("%c" + result + " : " + num + " : " + val, "background-color:" + color);


test(3.456, 3.45);
test(3.467, 3.46);
test(3.435, 3.43);
test(3.422, 3.42);

基本思路:

取号 将数字乘以将小数位移动到所需的有效数字位数 为数字添加底线以删除尾随数字 将数字除以得到正确的值

如果你想有一个尾随零,你需要使用toFixed(2),它将数字变成一个字符串。

function roundDown(num,dec) 
    return Math.floor(num*Math.pow(10,dec))/Math.pow(10,dec).toFixed(2);

并且测试用例需要更改为

test(3.456, "3.45");
test(3.467, "3.46");
test(3.435, "3.43");
test(3.422, "3.42");

另一个选项是正则表达式。

function roundDown(num,dec) 
    var x = num.toString().match(/(\d*(\.\d2))?/);
    return x ? parseFloat(x[0]) : "";
    //return x ? parseFloat(x[0]).toFixed(2) : "";

【讨论】:

【参考方案2】:

使用String操作来实现。

var n = 4.56789;
var numbers = n.toString().split('.');
result = Number(numbers[0]+"."+numbers[1].substr(0,2));
alert(result);

Fiddle

【讨论】:

@epascarello 已更新。谢谢【参考方案3】:

您将数字视为一串数字,而不是单个值,因此请将其视为字符串。-

function cutoff(n, cut)    
    var parts= String(n).split('.'), dec= parts[1];
    if(!cut) return parts[0];
    if(dec && dec.length>cut) parts[1]= dec.substring(0, cut);
    return parts.join('.');

var n= 36.938;
cutoff(n,2)

/*  returned value: (String)
36.93
*/

如果你想要一个数字,+cutoff(n,2) 就可以了。

【讨论】:

【参考方案4】:
function truncateDec(num, decplaces) 
    return (num*Math.pow(10,decplaces) - num*Math.pow(10,decplaces) % 1)/Math.pow(10,decplaces);

alert(truncateDec(105.678, 2)); // Returns 105.67
alert(truncateDec(105.678, 1)); // Returns 105.6

如果您不需要动态的小数位数,这可以进一步简化

function truncateDec(num) 
    return (num*100 - num*100 % 1)/100;

alert(truncateDec(105.678)); // Returns 105.67

它是如何工作的?

这个概念是,主要截断的工作原理是从原始小数除以 1 得到余数。余数将是小数位中的任何内容。余数运算符是 %

105.678 % 1 = 0.678

通过从原始数字中减去这个余数,我们将只剩下整数。

105.678 - 0.678 = 105

要包含x 的小数位数,我们需要先将原始数字乘以该小数位数的10 次方,从而将小数点向后移动x 的位置。在本例中,我们将采用x = 2

105.678 * 10^2 
= 105.678 * 100
= 10567.8

现在,我们通过再次减去余数来重复相同的过程。

10567.8 % 1 = 0.8
10567.8 - 0.8 = 10567

为了返回请求的位置数,我们将其除以 10^x

10567 / 10^2
= 10567 / 100
= 105.67

希望对你有帮助!

【讨论】:

以上是关于如何在不向上或向下舍入的情况下获得精确的数字[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何在不进行任何舍入的情况下将浮点数转换为小数点后 4 位?

JS实现浮点数精确舍入小数点

javascript 向上或向下舍入数字

r 将数字向上或向下舍入到一个漂亮的数字

MATLAB 舍入函数 - 它如何向上或向下舍入 0.5?

Powershell:将分数转换为整数 - 令人惊讶的舍入行为