1. Куча / Говнокод #12003

    +95

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    7. 7
    8. 8
    9. 9
    println    (13.0 to 14.0 by 0.1);
    println    (1.3 to  1.4 by 0.01);
    println    (7.0 to 8.2 by 0.3);
    
    //Output:
    NumericRange(13.0, 13.1, 13.2, 13.3, 13.4, 13.5, 13.6, 13.7, 13.8, 13.9, 14.0)
    NumericRange(1.3, 1.31, 1.32, 1.33, 1.34, 1.35, 1.36, 1.37, 1.38, 1.39)
    java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
    	at java.math.BigDecimal.divide(BigDecimal.java:1616)

    Скала - говно. Вернее даже говнище. И это достойно отдельного поста.
    Консолька для запуска тут:
    http://www.simplyscala.com/

    Запостил: 3.14159265, 25 Октября 2012

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

    • 12003 - счастливый
      Интересно, чем это вызвано?
      Ответить
    • Видимо 1.2 у нее не делится на 0.3...
      Ответить
    • $ scala -e "println(7.0 to 8.2 by 0.3)"
      NumericRange(7.0, 7.3, 7.6, 7.8999999999999995)

      УМВР ЧЯДНТ?

      >http://www.simplyscala.com/
      Понятно.
      Ответить
      • Еще одно из весомых преимуществ скалы - код везде работает одинаково.
        А вот это тоже так должно быть:
        >> 14.0)
        >> 1.39)
        Ответить
        • >код везде работает одинаково
          Предполагаю, что с точностью до версии JVM.

          >А вот это тоже так должно быть
          IEEE 754 же (который используется JVM):
          1.3 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 == 1.4000000000000001
          Ответить
          • >что с точностью до версии JVM.
            Да причем тут JVM? Язык программирования, который претендует на звание кроссплатформенного не должен зависеть от виртуальной машины на которой он запущен.
            Это же логическая надстройка над JVM, а жабомашина - это просто средство.
            Вот сама JVM не зависит от процессора. 64-битный он или 16-битный, int в ней всегда 32 бита. А плавающая точка - IEEE 754.
            Ответить
            • >претендует на звание кроссплатформенного
              С чего вы взяли, что кроссплатформенность подразумевает отказ от формата IEEE 754? Это где-то декларируется в документации Scala? Scala использует тот же формат чисел с плавающей точкой, что и Java, причем именно потому, что использует Java как основу. И он кроссплатформенно поддерживает формат IEEE 754.

              Впрочем, вот вам для успокоения точная арифметика:
              $ scala -e "println(BigDecimal(1.3) to 1.4 by 0.01)"
              NumericRange(1.3, 1.31, 1.32, 1.33, 1.34, 1.35, 1.36, 1.37, 1.38, 1.39, 1.40)
              Ответить
              • Да уж.
                Очень точная. Точнее некуда
                object Main extends App {
                    println(BigDecimal(1.3) to BigDecimal(1.3999999999999999) by BigDecimal(0.01))
                
                }
                NumericRange(1.3, 1.31, 1.32, 1.33, 1.34, 1.35, 1.36, 1.37, 1.38, 1.39, 1.40)

                http://ideone.com/77vJA4
                Ответить
                • Я до этого момента сомневался, но теперь все кристально ясно - вы типичный неосилятор. Но не буду голословным:
                  $ scala -e "println(1.3999999999999999)"
                  1.4

                  Дело в том, что вы в конструктор BigDecimal передаете double (в формате IEEE 754), который округляется еще до того, как попадает в конструктор. Неудивительно, что при этом вы получаете 1.4.

                  Да вас еще кто-то и плюсует за ваш блистательный анализ языка.
                  Ответить
                  • http://ideone.com/eGrE2C
                    У меня еще достаточно аргументов и примеров что ваша Скала - говно:
                    object Main extends App {
                        val one=BigDecimal(1)
                        val zero=BigDecimal(0)
                        println(zero to one by one/BigDecimal(7))
                        
                        println(zero to one by one/BigDecimal(3))
                    }
                    //Output:
                    //NumericRange(0, 0.142 0.285 0.428 0.571 0.714, 0.857)
                    //NumericRange(0, 0.333, 0.666, 0.999)


                    >Да вас еще кто-то и плюсует за ваш блистательный анализ языка.
                    Плюсуют потому что никаких аргументов от адептов скалы кроме как неловких попыток охарактеризовать поплеваться говном в меня
                    >Нет, случилось так, что ты имбецил.
                    >вы типичный неосилятор.

                    И отмазок типа "версия не та", "JVM неправильная", "платформа неудачная"
                    не слышно.
                    Ответить
          • Хорошо. Прочь слова. Возьмем пример:
            есть груви, который тоже работает на underlying JVM. Причем работает нормально:
            1.3.step(1.4, 0.01){ print "$it "}
            println ""
                13.step(14, 0.1){ print "$it "}
            println ""
                13.0.step(14.0, 0.1){ print "$it "}
            Result:
            1.3 1.31 1.32 1.33 1.34 1.35 1.36 1.37 1.38 1.39 
            13 13.1 13.2 13.3 13.4 13.5 13.6 13.7 13.8 13.9 
            13.0 13.1 13.2 13.3 13.4 13.5 13.6 13.7 13.8 13.9

            И как же так? Случилось чудо?
            http://ideone.com/cX1tRK
            Ответить
            • Нет, случилось так, что ты имбецил. В Groovy по дефолту используется BigDecimal, вот и все. Теперь попробуй с нормальным Double то же самое сделать.
              Ответить
    • Это всё клёво, но как автор вообще представляет себе поддержку ФПУ без этих побочных эффектов?
      Перегрузка оператора <=, чтобы сам добавлял нужное эпсилон? А какое эпсилон нужно?
      Ответить
      • >ФПУ без побочных эффектов
        Ага. Хаскель недостаточно чист. Он использует разрушающие присваения для регистров процессора
        Ответить

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