Как сравнить только дробные части чисел js
Перейти к содержимому

Как сравнить только дробные части чисел js

  • автор:

Number.isInteger()

Метод Number.isInteger() определяет, является ли переданное значение целым числом.

Интерактивный пример

Синтаксис

Number.isInteger(value)

Параметры

Значение, проверяемое на целочисленность.

Возвращаемое значение

Boolean сообщающий о том, является ли переданное значение целочисленным числом.

Описание

Если целевое значение является целым числом, возвращает true . Если значение NaN или Infinity , то возвращает false . Метод также возвращает true , если это вещественное число с точкой, которое может быть представлено в целочисленном виде.

Примеры

.isInteger(0); // true Number.isInteger(1); // true Number.isInteger(-100000); // true Number.isInteger(99999999999999999999999); // true Number.isInteger(0.1); // false Number.isInteger(Math.PI); // false Number.isInteger(NaN); // false Number.isInteger(Infinity); // false Number.isInteger(-Infinity); // false Number.isInteger("10"); // false Number.isInteger(true); // false Number.isInteger(false); // false Number.isInteger([1]); // false Number.isInteger(5.0); // true Number.isInteger(5.000000000000001); // false Number.isInteger(5.0000000000000001); // true 

Полифил

.isInteger = Number.isInteger || function (value)  return ( typeof value === "number" && isFinite(value) && Math.floor(value) === value ); >; 

Спецификации

Specification
ECMAScript Language Specification
# sec-number.isinteger

Совместимость с браузерами

BCD tables only load in the browser

Смотрите также

  • Объект Number , которому принадлежит этот метод.

Found a content problem with this page?

  • Edit the page on GitHub.
  • Report the content issue.
  • View the source on GitHub.

This page was last modified on 7 авг. 2023 г. by MDN contributors.

Your blueprint for a better internet.

MDN

Support

  • Product help
  • Report an issue

Our communities

Developers

  • Web Technologies
  • Learn Web Development
  • MDN Plus
  • Hacks Blog
  • Website Privacy Notice
  • Cookies
  • Legal
  • Community Participation Guidelines

Visit Mozilla Corporation’s not-for-profit parent, the Mozilla Foundation.
Portions of this content are ©1998– 2024 by individual mozilla.org contributors. Content available under a Creative Commons license.

Как правильно сравнить десятичные числа в JS?

Есть ли способ сравнить decimal числа с учетом того что последнее чило у них может быть + или — 1 ?

2.000000001 == 2 // true 4.9999999998 >= 4.9999999999 // true 7.99 == 8.02 //false // Так как 7.99 равен только 7.98, 7.99, 8.00 // А 8.02 == 8.01, 8.02, 8.03

Возможно ли такое сравнение чисел в JS и как это грамотно реализовать ?

  • Вопрос задан более трёх лет назад
  • 1280 просмотров

2 комментария

Простой 2 комментария

Сергей Соколов @sergiks Куратор тега JavaScript
сколько цифр после запятой ожидается?
Значения приходят как числа или как строки?
Сергей Соколов, Интересно, какое это имеет значение?
Решения вопроса 4

SagePtr

Еда — это святое
Math.abs(x — y) <= 0.01 к примеру Ответ написан более трёх лет назад Нравится 3 2 комментария
Это не будет работать 7.98 — 7.97 может быть 0,01000000005 к примеру

SagePtr

Дмитрий, изначально задача поставлена с непониманием работы вещественных чисел
Кратко о себе: Я есть

Определяем количество знаков после запятой и разницу между числами умножаем
и округляем до целого (все эти операции, чтобы избавиться от js-ных неточностей)
Если целое не больше единицы, значит равно.

Если количество знаков после запятой определяется по первому переданному числу, то код следующий

const compare= (v, v2) => < const parts = String(v).split('.') const pow = parts.length >1 ? parts.pop().length : 0 return Math.round(Math.abs(v - v2) * Math.pow(10, pow)) console.log(compare(7.98, 7.99)) // true console.log(compare(7.98, 7.97)) // true console.log(compare(7.98, 8)) // false console.log(compare(0.1, 0.15)) // true

если по числу с наибольшим количеством знаков после запятой, то такой

const compare= (v, v2) => < const parts = [v, v2].map(v =>String(v).split('.')) const pow = Math.max(. parts.map(v => v.length > 1 ? v.pop().length : 0)) return Math.round(Math.abs(v - v2) * Math.pow(10, pow)) console.log(compare(7.98, 7.99)) // true console.log(compare(7.98, 7.97)) // true console.log(compare(7.98, 8)) // false console.log(compare(0.1, 0.15)) // false

Ответ написан более трёх лет назад
Нравится 2 4 комментария
Сергей Соколов @sergiks Куратор тега JavaScript
compare(0.1, 0.15) // true
а должно быть false

Сергей Соколов, Я писал код с учетом того, что разница определяется по первому числу, как во всех приведенных примерах. Если определяется по числу с наибольшим количеством знаком после запятой, то так

const compare= (v, v2) => < const parts = [v, v2].map(v =>String(v).split('.')) const pow = Math.max(. parts.map(v => v.length > 1 ? v.pop().length : 0)) return Math.round(Math.abs(v - v2) * Math.pow(10, pow))

Demigodd

Demigodd @Demigodd Автор вопроса

Дмитрий,
Спасибо за подробный ответ.
Обязательно ли избавиться от js-ных точностей ?

Просто я получаю сумму неких чисел.
И делаю toFixed(10).

Тут мне и нужно такое сравнение что бы проверить такие числа.

sum = Number(sum.toFixed(10)); total = Number(total.toFixed(10)); sum == total

Сергей Соколов @sergiks Куратор тега JavaScript

DEATH2298, надо было этот важный момент в вопросе указать!

В этой ситуации достаточно Math.abs(sum — total) т.к. тут «ошибка округления» не зависит от последней ненулевой цифры, а заранее известна: 0.0000000001

Сергей Соколов @sergiks Куратор тега JavaScript

Можно прогнать числа через .toExponential() – это их нормализует:
(123.4567).toExponential() // «1.234567e+2»
и разбить на три части: до запятой [1, 10) , после запятой и степень.
Три целых: [1, 234567, 2]

Для проверки «равенства ±1» обязательно, чтобы степень (третье число) совпала.
Разность вторых чисел — буквально вычитаем и берем Math.abs() — если равна нулю, сравниваем только первые числа — на разность не выше 1. Если первые числа равны, то разность вторых не превышать 1 должна.

С таким же преобразованием числа легко реализовать и другие операции сравнения: >= ,

const fuzzy = < split: n => < const parts = n.toExponential().split('e') .map((p, i) =>i ? parseInt(p) : p.split('.').map(x => parseInt(x))); if (parts[0].length < 2) parts[0].push(0); return [parts[0][0], parts[0][1], parts[1]]; >, eq: (a, b) => < a = fuzzy.split(a); b = fuzzy.split(b); if (a[2] !== b[2]) return false; const diff = Math.abs(a[1] - b[1]); if (diff === 0) return Math.abs(a[0] - b[0]) >

Использовать: fuzzy.eq( 12.1234, 12.1233) // true

const tests = [ [1, 1, true], [111, 112, true], [0.001, .002, true], [0.001, .0025, false], [0.001, .003, false], [12.345, 1.2345, false], [123.88, 123.870, true], [-1.11111111, 1.11111110, false], [-1.11111111, -1.11111112, true], [2.000000001, 2, true], [4.9999999998, 4.9999999999, true], [7.9, 8.02, false], [7.99, 7.98, true], [7.99, 7.99, true], [7.99, 8.00, true], // НЕ ПРОХОДИТ! Надо этот случай предусмотреть, но я ушёл спать. ]; let allok = true; tests.forEach(test => < if (fuzzy.eq(. test) !== test[2]) < console.log("FAIL:", test); allok = false; >else < console.log("OK:", test); >>); console.log(allok ? 'All OK!' : "Some tests FAILED");

Math.round()

Метод Math.round() возвращает число, округлённое к ближайшему целому.

Синтаксис

Math.round(x)

Параметры

Описание

Если дробная часть числа больше, либо равна 0,5, аргумент будет округлён до ближайшего большего целого. Если дробная часть числа меньше 0,5, аргумент будет округлён до ближайшего меньшего целого.

Поскольку метод round() является статическим методом объекта Math , вы всегда должны использовать его как Math.round() , а не пытаться вызывать метод на созданном экземпляре объекта Math (поскольку объект Math не является конструктором).

Примеры

Пример: использование метода Math.round()

// Вернёт значение 20 x = Math.round(20.49); // Вернёт значение 21 x = Math.round(20.5); // Вернёт значение -20 x = Math.round(-20.5); // Вернёт значение -21 x = Math.round(-20.51); // Вернёт значение 1 (!) // Обратите внимание на ошибку округления из-за неточности арифметики с плавающей запятой // Сравните этот результат с результатом Math.round(1.005, -2) из следующего примера x = Math.round(1.005 * 100) / 100; 

Пример: корректировка округления десятичных дробей

// Замыкание (function ()  /** * Корректировка округления десятичных дробей. * * @param type Тип корректировки. * @param value Число. * @param exp Показатель степени (десятичный логарифм основания корректировки). * @returns Скорректированное значение. */ function decimalAdjust(type, value, exp)  // Если степень не определена, либо равна нулю. if (typeof exp === "undefined" || +exp === 0)  return Math[type](value); > value = +value; exp = +exp; // Если значение не является числом, либо степень не является целым числом. if (isNaN(value) || !(typeof exp === "number" && exp % 1 === 0))  return NaN; > // Сдвиг разрядов value = value.toString().split("e"); value = Math[type](+(value[0] + "e" + (value[1] ? +value[1] - exp : -exp))); // Обратный сдвиг value = value.toString().split("e"); return +(value[0] + "e" + (value[1] ? +value[1] + exp : exp)); > // Десятичное округление к ближайшему if (!Math.round10)  Math.round10 = function (value, exp)  return decimalAdjust("round", value, exp); >; > // Десятичное округление вниз if (!Math.floor10)  Math.floor10 = function (value, exp)  return decimalAdjust("floor", value, exp); >; > // Десятичное округление вверх if (!Math.ceil10)  Math.ceil10 = function (value, exp)  return decimalAdjust("ceil", value, exp); >; > >)(); // Округление к ближайшему Math.round10(55.55, -1); // 55.6 Math.round10(55.549, -1); // 55.5 Math.round10(55, 1); // 60 Math.round10(54.9, 1); // 50 Math.round10(-55.55, -1); // -55.5 Math.round10(-55.551, -1); // -55.6 Math.round10(-55, 1); // -50 Math.round10(-55.1, 1); // -60 Math.round10(1.005, -2); // 1.01 -- сравните этот результат с результатом Math.round(1.005*100)/100 выше // Округление вниз Math.floor10(55.59, -1); // 55.5 Math.floor10(59, 1); // 50 Math.floor10(-55.51, -1); // -55.6 Math.floor10(-51, 1); // -60 // Округление вверх Math.ceil10(55.51, -1); // 55.6 Math.ceil10(51, 1); // 60 Math.ceil10(-55.59, -1); // -55.5 Math.ceil10(-59, 1); // -50 

Спецификации

Specification
ECMAScript Language Specification
# sec-math.round

Совместимость с браузерами

BCD tables only load in the browser

Смотрите также

  • Math.abs()
  • Math.ceil()
  • Math.floor()
  • Math.sign() Экспериментальная возможность
  • Math.trunc() Экспериментальная возможность

Как у дробного числа откинуть целю часть и округлить до n чисел?

Проверка результата Для проверки подставляйте разные значения переменных a, b и n и проверяйте получившийся результат. Сравнения должны давать соответствующий результат true или false в зависимости от получившихся дробных частей. Примеры для проверки:

Для a = 13.123456789, b = 2.123, n = 5 дробные части: 12345, 12300. Для a = 13.890123, b = 2.891564, n = 2 дробные части: 89, 89. Для a = 13.890123, b = 2.891564, n = 3 дробные части: 890, 891. 

Критерии оценки Для любых значений a, b и n корректно вычисляются дробные части и выводятся результаты сравнения.

Отслеживать
13.7k 12 12 золотых знаков 43 43 серебряных знака 75 75 бронзовых знаков
задан 21 авг 2020 в 9:45
Andrew Wander Andrew Wander
51 2 2 серебряных знака 8 8 бронзовых знаков
похоже на задачу с codewars
21 авг 2020 в 11:34

5 ответов 5

Сортировка: Сброс на вариант по умолчанию

сам решил таким способом

 function getInteger(a,n)

Отслеживать
4,379 4 4 золотых знака 17 17 серебряных знаков 29 29 бронзовых знаков
ответ дан 21 авг 2020 в 10:16
Andrew Wander Andrew Wander
51 2 2 серебряных знака 8 8 бронзовых знаков
a — Math.floor(a) — бррррррр
21 авг 2020 в 13:45

это плохо? как по мне это самое правильное решение получилось. просто отнимаю дробное число от целого и затем умножаю на 10 в степени n. Тем самым перевел дробное число в целое. Ну а дальше уже сравнение и т.д.

21 авг 2020 в 19:17

Оно заменяется более красивым a % 1 . В целом решение вроде хорошее, но я не уверен, не может ли умножение на степень 10 внести дополнительную погрешность, поэтому в своём ответе использовал другой вариант.

22 авг 2020 в 10:58
как обходите getInteger(5.1, 1) = 0 ?
23 авг 2020 в 21:13

function fr(x, n) < var s = x.toFixed(100) return s.substr(s.indexOf(".") + 1, n).padEnd(n, 0) >for (var n = 1; n for (var n = 98; n
.as-console-wrapper.as-console-wrapper < max-height: 100vh >.as-console-row-code

А вообще, дробная часть числа получается так:

var x = 12.3456789012345 console.log(x % 1)

Отслеживать
ответ дан 21 авг 2020 в 13:44
123k 24 24 золотых знака 126 126 серебряных знаков 303 303 бронзовых знака
1.4%1 = 0.3999999999999999
21 авг 2020 в 13:49
@br3t, и что? Так и должно быть. i.stack.imgur.com/JJoYN.png
21 авг 2020 в 13:51
да, потому, наверное, лучше всего работать с этим как со строками
21 авг 2020 в 13:52

@br3t, но по условию в вопросе уже даны числа, а не строки. Если есть строка, то из моего решения достаточно выкинуть var s = x.toFixed(100)

21 авг 2020 в 13:59

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

21 авг 2020 в 14:05

Получить дробную часть числа можно так:

let number = 5.234 console.log(number.toString().split('.')[1]) 

Отслеживать
ответ дан 21 авг 2020 в 9:56
2,018 9 9 серебряных знаков 28 28 бронзовых знаков
А если number = 0.0000001 ?
21 авг 2020 в 12:03

@Yaant всё равно будет работать, у этого числа дробная часть 0000001 или ты хочешь сказать, что у чисел 0.1 и 0.0001 одинаковая дробная часть? =)

21 авг 2020 в 12:53
(0.0000001).toString() = «1e-7» со всеми вытекающими
21 авг 2020 в 14:08
@br3t не знал об этой особенности js, сегодня попробую =)
23 авг 2020 в 8:38

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

var number = 123.456789; // наше исходное число var fractionalPart = number - Math.floor(number); // его дробная часть fractionalPart -= 0.0005; fractionalPart -= 5 * Math.pow(10, -4); // 4 - число на единицу больше количества знаков, которые нужно оставить после запятой. var result = fractionalPart.toFixed(3); // дробная часть, округлённая до 3 знаков после запятой console.log(result); // 0.456

Отслеживать
ответ дан 21 авг 2020 в 13:31
2,304 1 1 золотой знак 8 8 серебряных знаков 20 20 бронзовых знаков
number — Math.floor(number) — бррррр
21 авг 2020 в 13:45
Кстати, округлять не просили, а в примерах явно видно truncate: 13.123456789 => 12345
21 авг 2020 в 14:43

Это не я округлил, а метод toFixed() 🙂 Сам я против. Но если отрезультата отнять 5 единиц самого младшего разряда, то получится без округления.

21 авг 2020 в 14:52

вот из-за этого toFixed я и решился задать тут вопрос этот) он явно не поможет в этой задаче из-за своей любви к округлению дробной части)

21 авг 2020 в 19:46
Поможет! (но не явно) 🙂 Я переделал ответ.
21 авг 2020 в 21:27

Сделал с помощью объектов Math.

let a = 13.123456789; let b = 2.123; let n = 5; /* let a = 13.890123; let b = 2.891564; let n = 2; let a = 13.890123; let b = 2.891564; let n = 3; */ // целая часть let aFloor = Math.floor(a); let bFloor = Math.floor(b); //дробная часть let aFract = (a % 1); let bFract = (b % 1); let aFractNormalized = Math.round( aFract * Math.pow(10, n) ); let bFractNormalized = Math.round( bFract * Math.pow(10, n) ); console.log('Для a = ', a); console.log('Для b = ', b); console.log('Целая часть a: ', aFloor); console.log('Целая часть b: ', bFloor); console.log('Дробная часть a: ', aFract); console.log('Дробная часть b: ', bFract); console.log('Нормализованная дробная часть a:', aFractNormalized); console.log('Нормализованная дробная часть b:', bFractNormalized); //результаты сравнения >, b', aFractNormalized > bFractNormalized); console.log('a < b', aFractNormalized < bFractNormalized); console.log('a >= b', aFractNormalized >= bFractNormalized); console.log('a  

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *