Почему действительно повышает:: вариант не обеспечивает оператор! =

ПРИМЕЧАНИЕ. - См. Редактирование 4, если важна трехзначная точность.

var discount = (price / listprice).toFixed(2);

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

Пример: http://jsfiddle.net/calder12/tv9HY/

Документация: https://developer.mozilla.org/en-US/docs/ Web / JavaScript / Reference / Global_Objects / Number / toFixed

Редактировать - Как упоминалось другими, это преобразует результат в строку. Чтобы избежать этого:

var discount = +((price / listprice).toFixed(2));

Редактировать 2 - Как также упоминалось в комментариях, эта функция не работает с некоторой точностью, например, в случае 1,005 она вернет 1,00 вместо 1,01. Если важна точность в этой степени, я нашел ответ: https://stackoverflow.com/a/32605063/1726511 Кажется, что он хорошо работает со всеми тестами, которые я пробовал.

Однако требуется одно небольшое изменение: функция в ответе, связанном выше, возвращает целые числа, когда округляет до единицы, поэтому, например, 99.004 вернет 99 вместо 99.00, что не идеально для отображения цен.

Редактировать 3 - Похоже, что toFixed на фактическом возврате все еще испортил некоторые числа, это окончательное редактирование работает. Черт возьми, так много переделок!

   var discount = roundTo((price / listprice), 2);

   function roundTo(n, digits) {
     if (digits === undefined) {
       digits = 0;
     }

     var multiplicator = Math.pow(10, digits);
     n = parseFloat((n * multiplicator).toFixed(11));
     var test =(Math.round(n) / multiplicator);
     return +(test.toFixed(digits));
   }

См. Пример Fiddle здесь: https://jsfiddle.net/calder12/3Lbhfy5s/

Редактировать 4 - Вы, ребята, убиваете меня. Редактировать 3 не удается на отрицательных числах, не разбираясь в том, почему просто проще справиться с превращением отрицательного числа в положительное, прежде чем выполнять округление, а затем повернуть его обратно, прежде чем вернуть результат.

function roundTo(n, digits) {
    var negative = false;
    if (digits === undefined) {
        digits = 0;
    }
        if( n < 0) {
        negative = true;
      n = n * -1;
    }
    var multiplicator = Math.pow(10, digits);
    n = parseFloat((n * multiplicator).toFixed(11));
    n = (Math.round(n) / multiplicator).toFixed(2);
    if( negative ) {    
        n = (n * -1).toFixed(2);
    }
    return n;
}

Скрипка: https://jsfiddle.net/3Lbhfy5s/79/

16
задан Drew Dormann 2 December 2011 в 16:27
поделиться

2 ответа

Думаю, он просто не добавлен в библиотеку. Boost.Operators на самом деле не поможет, потому что любой вариант был бы производным от boost :: operator :: equal_comparable. Дэвид Пьер прав, говоря, что вы можете это использовать, но ваш ответ также верен: новый оператор! = Не будет найден ADL, поэтому вам понадобится оператор using.

Я бы спросил об этом на список рассылки boost-users.

Редактировать из комментария @ AFoglia:

Семь месяцев спустя я изучаю Boost.Variant и натыкаюсь на это лучшее объяснение списков пропусков.

http: / /boost.org/Archives/boost/2006/06/105895.php[1287 visibleoperator== вызывает operator == для фактического класса, который сейчас находится в варианте. Аналогично, вызов operator! = также должен вызывать operator! = класса. (Потому что теоретически класс может быть определен так, что a! = B не то же самое, что ! (A == b) .) Это добавило бы еще одно требование, чтобы классы в варианте есть оператор ! = . (В ветке списка рассылки ведутся споры о том, можно ли сделать это предположение.)

12
ответ дан 30 November 2019 в 22:37
поделиться

Потому что в этом нет необходимости.

Boost имеет библиотеку операторов , в которой оператор! = Определяется как оператор ==

2
ответ дан 30 November 2019 в 22:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: