16.10.2012, 03:23
|
|
Кандидат Javascript-наук
|
|
Регистрация: 11.08.2011
Сообщений: 103
|
|
Инкремент числа с плавающей точкой
Объясните странное поведение операций с числами с плавающей точкой.
Мне надо в цикле производить увеличение целой части исходного числа на 1. Если, например, число от 11 до 15, то десятичная часть через определенный шаг цикла стает больше исходной. Пример:
var numsList = [];
var num = 12.001;
for (var i = 0; i <= 5; i++) {
numsList.push(num++);
}
alert(numsList);
В пример, числа нормально увеличиваются до 15.001, затем получаем 16.000999999999998 и т.д.
Надо чтобы десятичная часть оставалась постоянной. Можно ли как-то решить проблему?
|
|
16.10.2012, 03:38
|
|
Тлен
|
|
Регистрация: 02.01.2010
Сообщений: 6,584
|
|
Округлять до нужного знака, без вариантов.
__________________
29375, 35
|
|
16.10.2012, 04:29
|
|
Кандидат Javascript-наук
|
|
Регистрация: 11.08.2011
Сообщений: 103
|
|
Спасибо большое за пример реализации!
Я так понимаю это особенность вычислительного движка JS.
А такой вариант имеет право на жизнь?:
var numsList = [];
var num = 12.001;
var digits = /(?:\.)(\d+)/.exec(num);
for (var i = 0; i <= 5; i++) {
if (digits === null) {
numsList.push(num++);
} else {
numsList.push((num++).toFixed(digits[1].length) * 1);
}
}
alert(numsList);
alert(typeof numsList[5]);
|
|
16.10.2012, 04:45
|
|
Тлен
|
|
Регистрация: 02.01.2010
Сообщений: 6,584
|
|
Дзен-трансгуманист, чего-то я не особо вдупляю - накой такие сложности в твоей функции?
(function(a){
window.alert = function(){
a(Array.prototype.slice.call(arguments).join('\n'))
}
}(window.alert))
function maxFraction (value, digits) {
var fixed = (+value).toFixed(digits);
var i = fixed.length - 1;
loop: while (true) {
switch (fixed.charAt(i)) {
case "0": i--; continue;
case ".": i--; break loop;
}
break;
}
return fixed.slice(0, i+1);
}
Number.prototype.round = function(p){ //почему не так?
return +this.toFixed(p)
}
num = 0.1 + 0.2;
alert(
num,
maxFraction(num, 1),
num.round(1),
maxFraction(num+99, 1),
(num+99).round(1),
maxFraction(num, 0),
num.round(),
maxFraction(num, 5),
num.round(5)
)
__________________
29375, 35
Последний раз редактировалось Aetae, 16.10.2012 в 05:10.
|
|
16.10.2012, 05:01
|
|
Кандидат Javascript-наук
|
|
Регистрация: 11.08.2011
Сообщений: 103
|
|
В моей задаче есть два условия:
1. количество десятичных знаков наперед неизвестно (количество должно извлекаться из исходного числа)
2. должно возвращаться число (не строка)
Последний раз редактировалось antonM, 16.10.2012 в 05:03.
|
|
16.10.2012, 05:06
|
|
Тлен
|
|
Регистрация: 02.01.2010
Сообщений: 6,584
|
|
Сообщение от antonM
|
В моей задаче есть два условия:
1. количество десятичных знаков наперед неизвестно
2. должно возвращаться число (не строка)
|
Печально. Считай кол-во знаков базового числа и по нему округляй.
Xотя, в принципе, погрешность, если вычисления не идут подряд, накапливаться не будет, а потому достаточно округлять до десяти знаков - лишнее отбросится:
(function(a){
window.alert = function(){
a(Array.prototype.slice.call(arguments).join('\n'))
}
}(window.alert))
Number.prototype.round = function(p){
return +this.toFixed(p)
}
num = 0.1 + 0.2;
alert(
num,
num.round(10)
)
__________________
29375, 35
Последний раз редактировалось Aetae, 16.10.2012 в 05:10.
|
|
16.10.2012, 05:12
|
|
Кандидат Javascript-наук
|
|
Регистрация: 11.08.2011
Сообщений: 103
|
|
Спасибо. Вопрос вычислений не стоит. Надо заполнить диапазон ячеек инкрементным набором чисел отталкиваясь от числа в первой ячейке. Соответственно все должно быть красиво без внезапных выскакиваний чисел с умопомрачительным количеством десятичных знаков. Что-то на подобии того, как это делается аутофиллером в Экселе или ООО Кальк.
|
|
16.10.2012, 11:09
|
|
司会
|
|
Регистрация: 29.02.2012
Сообщений: 198
|
|
сделай тустринг, то что ДО точки преврати в число, инкриментируй, потом сделай тустринг, и вставь до точки в предыдущей строке, потом сделай пфрсфлоат. КЭП
|
|
16.10.2012, 11:39
|
|
junior
|
|
Регистрация: 29.11.2011
Сообщений: 3,924
|
|
Сообщение от antonM
|
Объясните странное поведение операций с числами с плавающей точкой.
|
IEEE 754
Сообщение от antonM
|
Спасибо. Вопрос вычислений не стоит. Надо заполнить диапазон ячеек инкрементным набором чисел отталкиваясь от числа в первой ячейке. Соответственно все должно быть красиво без внезапных выскакиваний чисел с умопомрачительным количеством десятичных знаков. Что-то на подобии того, как это делается аутофиллером в Экселе или ООО Кальк.
|
не понял, в чем проблема. Уже объяснили как это сделать.
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук
Последний раз редактировалось nerv_, 16.10.2012 в 11:50.
|
|
16.10.2012, 14:16
|
|
Кандидат Javascript-наук
|
|
Регистрация: 11.08.2011
Сообщений: 103
|
|
nerv_, за ссылочку спасибо. Вопрос собственно уже решен
|
|
|
|