Как сделать код с арифметикой кроссплатформенным?



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



Во-первых, разберемся насколько сильно результатам позволено расходиться. В документации разных методов из Math эта величина выражается в единицах ulp (unit in the last place). Это то, насколько увеличится число, если его битовое выражение увеличить на 1 бит. Для разных чисел значение ulp будет различаться. Получить его можно методом Math.ulp(x).



Если объявленной точности не хватает, на помощь придет класс StrictMath. В нём находится примерно такой же набор инструментов как в Math, но с повторяемыми результатами, которые можно получить стандартизованными алгоритмами на C.



Для обычных языковых выражений вроде инициализаторов и операторов введено понятие свойства FP-strict. Выражения с этим свойством будут кроссплатформенным. Чтобы добавить свойство всем операторам, на методе используется модификатор strictfp (о котором мы уже упоминали).



#Язык