Разбиение действительного числа на 2 числа

1

В качестве дополнения к моему ответу на этот вопрос я пытаюсь разбить реальное число таким образом, чтобы каждое из двух чисел отличалось на 1 в последней цифре (с учетом ограничений арифметического представления с плавающей запятой).

Например:

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

Чтобы уточнить, результирующие слагаемые должны содержать то же количество цифр, что и исходный номер.

Это то, к чему я придумал.

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 также будет работать. Любая помощь будет оценена по достоинству. Спасибо!

  • 0
    Вы заботитесь о точности с плавающей точкой, вызывающей проблемы?
  • 0
    @NickA Если это угловой случай, на который я указал, то нет, это не имеет значения.
Теги:

2 ответа

1
Лучший ответ

Быстро взбить это, это соответствует вашим потребностям?

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:

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))

Вы заметите, что я думал, что вам нужно преобразовать строку в строку и получить число десятичных знаков.

1

Вот пример python:

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)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню