- Целые числа (в том числе машинные целые числа) по операции сложения / умножения.
- Строки по операции конкатенации.
- Предикаты по операции конъюнкции / дизъюнкции.
- ... и многие многие другие.
Однако некоторые множества не являются ассоциативными, например, числа с плавающей точкой (по сложению / умножению).
Это легко проверить. Для этого мы воспользуемся библиотекой functionaljava, в которой есть возможность тестирования свойств (аля Haskell QuickCheck). Тест будет выглядеть следующим образом:
Property prop = Property.property(Arbitrary.arbDouble, Arbitrary.arbDouble, Arbitrary.arbDouble,
(x, y, z) -> Property.prop((x + y) + z == x + (y + z)));
CheckResult check = prop.check();
System.out.println("Passed: " + check.isPassed());
Если выполнить этот код, то он выведет false. У класса CheckResult также можно спросить, какие именно числа нарушают ассоциативность:for (List<Arg<?>> args : check.args()) {
double x = (Double) args.index(0).value();
double y = (Double) args.index(1).value();
double z = (Double) args.index(2).value();
System.out.printf("(%s + %s) + %s = %s%n", x, y, z, (x + y) + z);
System.out.printf("%s + (%s + %s) = %s%n", x, y, z, x + (y + z));
}
Этот код выведет примерно следующее:
(5.094895128230203 + -7.839963840335238) + -1.8589779099062191 = -4.604046622011254
5.094895128230203 + (-7.839963840335238 + -1.8589779099062191) = -4.6040466220112535
Как видите, при разной расстановке скобок результаты будут разными.
Комментариев нет:
Отправить комментарий