Как размножаться в Javascript? проблемы с десятичными знаками

У меня есть следующий код в Javascript:

var m1 = 2232.00;
var percent = (10/100);
var total = percent*m1;
alert(total);

Проблема в том, что переменная "total" дает мне "223.20000000000002", и она должна быть "223.2", что я должен сделать, чтобы получить правильное значение?

Ответ 1

.toFixed() - лучшее решение. Оно будет содержать только две цифры после точки.

Опыт 1:

var value = 3.666;
value.toFixed(2); //Output : 3.67

Опыт 2:

var value = 3.0000;
value.toFixed(2); //Output : 3.00

Ответ 2

Вы не можете получить точное значение. Это основная проблема с числами с плавающей запятой.

Вы можете принудительно фиксировать число десятичных чисел с помощью toFixed:

alert(total.toFixed(2));

Однако имейте в виду, что это оставит конечные нули, которых вы, возможно, не захотите. Вы можете удалить их с помощью .replace(/0+$/,'');

Ответ 3

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

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

Math.round( total * 10 ) / 10

Однако, как отмечают различные люди, неточное значение - это всего лишь число чисел с плавающей запятой.

См. Вопросы, связанные с комментариями, для получения более подробной информации.

Ответ 4

Я нашел ответ, используя следующие страницы, благодаря Димитрию:

Платформа с плавающей точкой для JavaScript

Я решил использовать следующие классы, потому что мне нужны точные значения операций, и они связаны с денежными операциями:

Ответ 5

Это можно сделать хорошо с внешней библиотекой, называемой decimal.js, которая предоставляет Decimal тип для JavaScript. Он также доступен для узла на npm. Ниже приведен пример, который повторяет исходный пример из gustavomanolo с использованием decimal.js.

// Decimal type provided by decimal.js (http://mikemcl.github.io/decimal.js/)
var m1 = new Decimal( 2232.00 );
var percent = new Decimal( 10/100 );
var total = m1.mul(percent);
console.log( 'Total:', total );
<script src="https://cdnjs.cloudflare.com/ajax/libs/decimal.js/7.2.3/decimal.min.js"></script>

Ответ 6

total.toFixed(2) может помочь. Но учтите, что total переменная be будет указана в строку.

Ответ 7

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

function decimalPlaces(num) {
    var match = (''+num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);
    if (!match) { return 0; }
    return Math.max(
        0,
        // Number of digits right of decimal point.
        (match[1] ? match[1].length : 0)
        // Adjust for scientific notation.
        - (match[2] ? +match[2] : 0));
}

И тогда для вашего окончательного ответа "total" вы делаете

total = total.toFixed(decimalPlaces(a)+decimalPlaces(b));

где a, b - ваши номера

Ответ 8

Просто попробуй

var x = 0.07;
console.log((x+1)*100 - 100);

теперь замените значение x для других значений ;-)

Ответ 9

Операторы "*" и "/" работают не всегда идеально, например:

32.09 * 100 = 3209.0000000000005
100 / (1 / 32.09) = 3209.0000000000005

Решение:

Одно из простых решений - использовать десятичные дроби, используя.toFixed(2), где "2" - это количество требуемых десятичных цифр. Но вы должны принять во внимание, что это возвращает вам String, и оно округляет значение.

45.6789.toFixed(2) —> "45.68" as String

Другой вариант, наиболее полный, использует.toLocaleString, который правильно преобразовывает число в нужный вам код страны. Вы можете установить пару параметров, чтобы значения десятичных дробей всегда были равны 2. Это также возвращает вам строку:

(654.3453).toLocaleString(
  'en-US',
  {minimumFractionDigits: 2, maximumFractionDigits: 2},
) —> "654.35" as String

Если вам нужно это как число, вы можете заключить его в число (...):

Number((654.3453).toLocaleString(
  'en-US',
  {minimumFractionDigits: 2, maximumFractionDigits: 2},
)) —> 654.35 as Number

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

Math.trunc(32.09); —> 32 as Number  
(32.09).toFixed(0); —> "32" as String
32.09 | 0; —> 32 as Number

Ответ 10

Вы могли бы сделать

var total = +(percent*m1).toPrecision(15);

223.2 === total;          // true
223.2 === 0.1*2232.00;    // false

Ответ 11

Если вы используете Angular, я сделал компонент для этого.

Установить с подставкой

bower install angular-floating-point --save

Применение

var pretty = floatingPoint.makePretty(6.1*6);

Ниже приведена демонстрация → https://mattspaulding.github.io/angular-floating-point
Вот источник → https://github.com/mattspaulding/angular-floating-point

Попробуйте сами с этим фрагментом ниже.

 angular.module('myApp', ['floatingPoint'])
  .controller('myCtrl', function ($scope, floatingPoint) {

      $scope.calculate = function () {
        $scope.result =$scope.num0*$scope.num1;
        $scope.prettyResult=floatingPoint.makePretty($scope.result)
      }

      $scope.num0=6.1;
      $scope.num1=6;
      $scope.calculate();

    });
 
<html>

<head>
  <title>My Angular App</title>
  <script src='//code.jquery.com/jquery-latest.min.js'></script>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
  <!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">

<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<script src="https://rawgit.com/mattspaulding/angular-floating-point/master/dist/angular-floating-point.min.js"></script>
</head>

<body ng-app="myApp" ng-controller="myCtrl">
    <div class="row" style="padding-top: 10px;text-align:center">
      <label>(try me) ==> </label>
      <input ng-model="num0" ng-change="calculate()" style="width:100px; height:30px">
      X
      <input ng-model="num1" ng-change="calculate()" style="width:100px; height:30px">
    </div>
    <div class="row" style="padding-top: 50px;">
      <div class="col-xs-6">
        <label style="float: right;">Ugly calculation:</label>
      </div>
      <div class="col-xs-6">
        <label style="float: left;">{{result}}</label>
      </div>
    </div>
    <div class="row" style="padding-top: 20px;">
      <div class="col-xs-6">
        <label style="float: right;"><span style="color:blue">Angular Floating Point</span> calculation:</label>
      </div>
      <div class="col-xs-6">
        <label style="float: left;">{{prettyResult}}</label>
      </div>
    </div>

</body>

Ответ 12

Я нашел очень простое решение. Оператор * немного разбит, когда речь идет о десятичных числах, но оператор / нет. Умножение легко трансформируется в деление, так как a • b = a/(1/b)

function times(a, b) { return a/(1/b) }

Просто замените percent * m1 times(percent, m1).

Обновление: он не работает все время.

Ответ 13

Я получил следующее решение:

function decimalmultiply(a, b) {
    return parseFloat((a * b).toFixed(12));
}

10.50*30.45=319.72499999999997
decimalmultiply(10.50,30.45)=319.725

Этот метод возвращает число, а не строку, без усечения значащих десятичных знаков (до 12).