关于javascript:将实数拆分为2个加数

Splitting a real number into 2 addends

作为我对这个问题的答案的扩展,我尝试用一种方法来分裂一个实数,即两个数中的每一个在最后一个数字中相差最多1个(受浮点算术表示的限制)。

例如:

1
2
3
4
5
7     => 4, 3
7.2   => 3.6, 3.6
7.3   => 3.7, 3.6 (or 3.5999999999999996) -- I understand this is a corner case and it is alright
7.25  => 3.63, 3.62
7.225 => 3.613, 3.612

为了澄清,合成加数必须包含与原始数字相同的数字位数。

这就是我到目前为止想出来的。

1
2
3
4
5
6
7
8
9
10
var x = 7.3;

if(x != Math.round(x)) {
    var p1 = Math.ceil((x  / 2) * 10) / 10;
} else {
    var p1 = Math.ceil(x  / 2);
}
var p2 = x - p1;

console.log(p1, p2);

这适用于整数和小数点后一位的数字。我相信一般的解决办法是找出点后有多少个数字。

我不确定如何做到这一点,但我认为有一种解决方案需要转换成字符串,在'.'上拆分,找到数字计数,然后乘以/除以10的适当幂…基本上扩展了我编写的代码,所以它适用于任意数字。

首选JavaScript解决方案,但也可以使用Python解决方案。任何帮助都将不胜感激。谢谢您!


下面是一个python示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import math

def split_num(num):
    i = 0
    while (num != round(num, i)):  ## NOTE: guaranteed to terminate
        i = i + 1
    p1 = math.ceil( ( 10**i * num ) / 2) / 10**i  ## using 10**i rounds to the appropriate decimal place
    return (p1, num - p1)

## test output
if __name__ =="__main__":
    print(split_num(10))
    print(split_num(10.1))
    print(split_num(10.12))
    print(split_num(10.123))
    print(split_num(10.1234))
    print(split_num(7.3))

>>> python split_num.py
(5.0, 5.0)
(5.1, 5.0)
(5.06, 5.06)
(5.062, 5.060999999999999)
(5.0617, 5.0617)
(3.7, 3.5999999999999996)

很快把这个搅起来,它符合你的需要吗?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function GenerateAddends(n){
    if(n == Math.round(n)){
        return [Math.round(n/2),n-Math.round(n/2)];
    }else{
        var len = n.toString().split(".")[1].length
        return [
            Math.round(n/2 * Math.pow(10,len)) / Math.pow(10,len),
            n - Math.round(n/2 * Math.pow(10,len)) / Math.pow(10,len)
        ]
    }
}

console.log(GenerateAddends(7))
console.log(GenerateAddends(7.2))
console.log(GenerateAddends(7.3))
console.log(GenerateAddends(7.25))
console.log(GenerateAddends(7.225))

或者使用ecmascript 2016:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function GenerateAddends(n){
    if(n == Math.round(n)){
        return [Math.round(n/2),n-Math.round(n/2)];
    }else{
        var len = n.toString().split(".")[1].length
        return [
            Math.round(n/2 * 10**len) / 10**len,
            n - Math.round(n/2 * 10**len) / 10**len
        ]
    }
}

console.log(GenerateAddends(7))
console.log(GenerateAddends(7.2))
console.log(GenerateAddends(7.3))
console.log(GenerateAddends(7.25))
console.log(GenerateAddends(7.225))

你会注意到我和你转换成一个字符串并得到小数位数一样的想法。