JavaScript: округлити до числа десяткових знаків, але позбавити зайвих нулів


85

Ось сценарій: я отримую, .9999999999999999коли мав би отримувати 1.0.
Я можу дозволити собі втратити точність після коми, тому я використовую .toFixed(15), який вид роботи працює.

Округлення працює, але проблема в тому, що мені дали 1.000000000000000.
Чи є спосіб округлити до числа знаків після коми, але позбавити зайвого пробілу?

Примітка: .toPrecisionце не те, що я хочу; Я хочу лише вказати, скільки чисел після десяткової коми.
Примітка 2: Я не можу просто використовувати, .toPrecision(1)тому що мені потрібно дотримуватися високої точності для чисел, які насправді мають дані після десяткової коми. В ідеалі було б рівно стільки десяткових знаків, скільки потрібно (до 15).


Справа в тому, що .toFixed повертає рядок, тому просто обертання його через число, а потім повернення до рядка перетворить його без кінцевих нулів.
Ніл

@Nathan: просто для роз'яснення. Ви просто хочете видалити кінцеві нулі в рядку, який ви отримали за допомогою toFixed ()?
Іржі Криз,

Відповіді:


141
>>> parseFloat(0.9999999.toFixed(4));
1
>>> parseFloat(0.0009999999.toFixed(4));
0.001
>>> parseFloat(0.0000009999999.toFixed(4));
0

4
Не забудьте ввести їх у дужки, коли обробляєте від’ємні числа: -2.34.toFixed(1)повертається -2.3завдяки перевазі оператора .
Константин Ван

1
Використання оператора unary + повинно бути швидшим за parseFloatфункцію: +number.toFixed(13)Цей вираз також може бути використаний для видалення неточностей номерів JavaScript, як у 10000000000000045.
ygoe


19

Як я розумію, ви хочете видалити кінцеві нулі в рядку, який ви отримали через toFixed(). Це операція чистого рядка:

var x = 1.1230000;
var y = x.toFixed(15).replace(/0+$/, "");  // ==> 1.123

6
Ви єдиний, хто справді відповів на питання .. дякую!
Mugen

4
Це залишає крапку на круглих цифрах ("100.00" => "100")
pckill

5
@pckill, якщо ви не хочете, щоб крапку можна було включити у регулярний вираз, щоб замінити ( ...replace(/\.?0+$/, "");).
Zach Snow

Це не вдається на 0 і -0, оскільки 0стає порожнім рядком ""і -0стає -, і жодне з них не очікується (на здогадка). @ zach-snow запропоноване вами рішення також не вдається на 0 і -0.
робокат

@Mugen, в чому була проблема з відповіддю Гуса?
триз

9

Number(n.toFixed(15)) or +(n.toFixed(15)) перетворить десятковий рядок із 15 знаків у число, видаливши кінцеві нулі.


1
Думав, я б на це звернув увагу, + (n.toFixed (...)) набагато ефективніше, ніж parseFloat. Не знаю, чому, але він також ефективніший, ніж Number у Chrome.
Доміно

8

Якщо ви повернете значення, яке повертається до числа, ці нульові нулі будуть скинуті. Це також менш багатослівно, ніж parseFloat()є.

+(4.55555).toFixed(2);
//-> 4.56

+(4).toFixed(2);
//-> 4

При цьому використовується унарний оператор + , так що якщо використовувати це як частину операції рядка вам необхідно мати Інфікси + перед ним: var n=0.9999999999999999; console.log('output ' + +n.toFixed(2));. FYI одинарний + перед рядком перетворює його в число. З MDN: Unary + може:

перетворює рядкові подання цілих чи значень з плаваючою точкою, а також нерядкові значення true, false та null. Підтримуються цілі числа як у десятковому, так і у шістнадцятковому (з префіксом "0x") форматах. Підтримуються від’ємні числа (правда, не для шістнадцяткового). Якщо він не може проаналізувати певне значення, він оцінить значення NaN.


@robocat Я щойно зробив просту перевірку; +(4.1).toFixed(4)є 4.1в Chrome 60 .
Константин Ван

Я не розумію. З якої причини ця відповідь отримала проти?
Константин Ван

@K Ви мали рацію, тому я видалив свій попередній коментар і додав до відповіді (я думаю, що використовував інфікс + із рядком на lhs, а не правильно, використовуючи одинарний +. Зазвичай я обережніший!
Вітаю

Ця відповідь все ще працює з NaN, Infinity, -Infinity, 3e30 та 0. Деякі інші відповіді не вдаються у деяких кутових випадках.
robocat

(4) .toFixed (2) -> "4.00" в Chrome 60.0.3112.113
Daniel Que

1

Жодне з них насправді не дало мені того, що я шукав, виходячи із заголовка запитання, який, наприклад, становив 5,00 5 і 5,10 5,1. Моє рішення було таким:

num.toFixed(places).replace(/\.?0+$/, '')

'5.00'.replace(/\.?0+$/, '') // 5
'5.10'.replace(/\.?0+$/, '') // 5.1
'5.0000001'.replace(/\.?0+$/, '') // 5.0000001
'5.0001000'.replace(/\.?0+$/, '') // 5.0001

Примітка: регулярний вираз працює, лише якщо places > 0

PS https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed


Не вдається увімкнути 5e30(змінює номер на 5e3). Кутові випадки диявольські!
robocat

0

Існує кращий метод, який зберігає точність, а також позбавляє нулів. Для цього потрібно ввести число, і за допомогою якоїсь магії кастингу витягнуть будь-які кінцеві нулі. Я виявив, що 16 є границею точності для мене, що є досить непоганим, якщо ви не ставите супутник на Плутон.

function convertToFixed(inputnum)
{

      var mynum = inputnum.toPrecision(16);
//If you have a string already ignore this first line and change mynum.toString to the inputnum

      var mynumstr = mynum.toString();
    return parseFloat(mynumstr);
    }
    alert(convertToFixed(6.6/6));

0

toFixed()Метод форматує з numberвикористанням нотації з фіксованою точкою, і повертає string.

Він застосовує стратегію округлення вдвічі .

(0.124).toFixed(2); // returns 0.12
(0.125).toFixed(2); // returns 0.13

Як ви вже описали, це справді також призведе до (потенційно непотрібних) нульових нулів.

(0.001).toFixed(2); // returns 0.00

Можливо, ви не захочете позбутися тих нулів, які виходять за межі, по суті, ви можете просто перетворити їх назад у number. Для цього існує багато способів.

+(0.001).toFixed(2); // the shortest

Для огляду різних методів перетворення рядків у числа перегляньте це запитання, на яке є кілька чудових відповідей.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.