1. 1C / Говнокод #25236

    0

    1. 1
    Сумма = Цел(Окр(Сумма * 1000, 0, 1)) / 1000;

    Или я мандаринов переел, или от этого портал должен открыться

    Запостил: valchara, 27 Декабря 2018

    Комментарии (42) RSS

    • Допустим, Сумма = 1234.56789
      Тогда:
      Сумма = Цел(Окр(1234.56789 * 1000, <ЧислоЗнаковДробнойЧасти=0>, <1.5 как 2>)) / 1000 = 1234.568


      "Цел" лишнее, и не понятно для чего так мудрёно.
      Ответить
      • Но ведь Окр(1234.56789,3,1)=1234.568
        Нафига вся эта мистика?
        Ответить
        • Мысль зрела так плавно, что пошли дефекты. Такое часто бывает, когда правишь неизвестно чей код с частотой раз в полгода и разбираться времени нет.
          Ответить
          • Блджад, это код из типовой бульбо-бухгалтерии, которому два с половиной года.
            Внезапно под 2019 поменялась математика. И кого-то ждет сюрприз, при мутном стечении цифр, который охеуеешь ловить отладчиком.
            Ответить
      • > "Цел" лишнее, и не понятно для чего так мудрёно.

        LOL. Это стандартный метод в *С/С++* для того что бы мусор из double значений подчищать. После многочисленых делений/умножений/этц, там начинает гавно после >7 знака после запятой накапливатся. Если даблы вот так не подчищать - с топорной конвертацией в целое число - то после большого количества операций могут появится неожиданные ошибки.

        Про применимость к 1С (или базам с ихними NUMBER) не в курсе.
        Ответить
        • > неожиданные ошибки
          Ну а что ты хотел от двоичной экспоненты и мутной разрядности?
          Ответить
        • Нету там никаких даблов.
          Это вообще кусок древней глобальной функции для округления денежных величин. Используется более 835 раз в разных местах. Нахуя там появился элемент внезапной лотереи с блэкджеком и экспонентами мне непонятно. От этого у меня бомбит и за вариантами сюда пришел.

          Функция глОкругление(Сумма, ДатаДок = "") Экспорт
          Сумма = Цел(Окр(Сумма * 1000, 0, 1)) / 1000;

          Точность=2;
          Если ПустоеЗначение(ДатаДок) = 0 Тогда
          Если ДатаДок < глДатаДеноминации Тогда
          Точность = 0;
          КонецЕсли;
          КонецЕсли;
          Возврат Окр(Сумма, Точность, 1);
          КонецФункции
          Ответить
          • > Нету там никаких даблов.

            1. Я сказал что не знаю что там в 1С.

            2. От тюрьмы до от сумы не зарекайся. Даже SQL умеет даблы. (И 1С сидит поверху базы, я догадываюсь.) Я видел нечищеные даблы в/из базы туды сюды один к одному переливались. (И ни одна из Тоадов/Тулзов не показывала double'ы с полной точностью - почему народ почти 2 месяца убил на поиск источника проблемы.)

            В том случае было все совсем плохо: подсчёт налогов (смешные числа типа 13% или 16%) + кастомер хотел что бы числа с более высокой точностью чем нужно хранились (типа, не 2 знака (центы), а 5 знаков).
            Ответить
      • > <1.5 как 2>
        Это режим округления так задается? Наглядненько.
        Ответить
        • <тучи как люди>
          Ответить
        • Гуглёжка показывает, что там три варианта: «1.5 как 2», «Всегда в меньшую», «Всегда в большую».

          А я всё никак не могу запомнить, чем в сишке отличаются floor от ceil.
          Ответить
          • Что за угловые скобки? Это как ${ в "PHP", " Perl" и "TCL"}?
            Ответить
            • Это копипаста из хелпа, так параметры обозначают
              Ответить
          • > floor от ceil
            А вот англоговорящим они очевидны - пол и потолок.
            Ответить
      • Посчитай, что вернет функция при Сумма = 0.002 с Цел и без Цел.
        После чего станет понятно, почему именно так.

        upd. Не, что-то затупил. Все нормально :)
        Ответить
    • use strict;
      use warnings;
      
      
      my $n = 14.88;
      $n *= 1000000;
      $n /= 1000000;
      $n += 0.01;
      
      print $n; # 14.89

      и по этому я за перл
      Ответить
      • <?php
        $n = 14.88;
        $n *= 1000000;
        $n /= 1000000;
        $n += 0.01;
        
        print $n; # 14.89

        И поэтому я за "PHP".
        Ответить
        • irb(main):001:0> n = 14.88
          => 14.88
          irb(main):002:0> n *= 1000000
          => 14880000.0
          irb(main):003:0> n /= 1000000
          => 14.88
          irb(main):004:0> n += 0.000001
          => 14.880001
          irb(main):005:0>

          а я заруби
          Ответить
          • а я за питон
            Python 2.7.14 (v2.7.14:84471935ed, Sep 16 2017, 20:19:30) [MSC v.1500 32 bit (In
            tel)] on win32
            Type "help", "copyright", "credits" or "license" for more information.
            >>> n = 14.88
            >>> n *= 1000000
            >>> n /= 1000000
            >>> n
            14.88
            Ответить
            • да и луа не плох
              local n = 14.88
              n = n * 1000000
              n = n / 1000000
              n = n + 0.01
              print(n) --14.89
              Ответить
              • Задание: найти язык который плох.
                Ответить
                • Си, Паскаль. Возможно, ещё какой-нибудь «низкоуровневый».
                  Ответить
                  • Проверь.
                    Ответить
                  • Поясните мысль.
                    Нет, ну, можно, конечно, написать int n = 14.88; , а потом сказать "Ага!" и пойти дальше валить лес тяжелыми железными топорами, но смысл?
                    Ответить
                    • #include <stdio.h>
                      
                      int main(){
                          long long n = 1488;
                          n*=10000000;
                          n/=10000000;
                          n+=1;
                          printf("%lld.%lld\n", n/100, n%100);
                      }
                      https://ideone.com/DCrpBR

                      Именно поэтому я за фиксед
                      Ответить
                    • Ну с такими числами всё хорошо:
                      #include <stdio.h>
                      
                      int main() {
                        double n = 14.88;
                        n = n * 1000000;
                        n = n / 1000000;
                        n = n + 0.00001;
                        printf("%f\n", n); // выведет 14.880010
                        printf("%g\n", n); // выведет 14.88
                        return 0;
                      }


                      С другими числами могут вылезти ошибки перевода из двоичной в десятичную.
                      Ответить
                      • Питония соснула:
                        >>> 0.3*3
                        0.89999999999999991
                        А в сишке всё норм.
                        Ответить
                        • Даже "PHP" не соснул.

                          А в Руби получается 0.8999999999999999.
                          Ответить
                        • Там небось разница в один ULP, а вы сразу пиписьки мерить побежали
                          https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
                          Ответить

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