Оставлю для будущих поколений..
Поделюсь своими наблюдениями на тему 2 задачи под названием "Приблизительное значение".
Для начала советую не спеша изучить процесс перевода десятичного числа в двоичную систему счисления числа с плавающей точкой. После изучения этой темы вам будет известно как число с плавающей точкой хранится в памяти: 1 бит хранит знак, 8 битов хранят экспоненту, оставшиеся 23 бита хранят мантиссу. После ручного перевода числа с плавающей точкой в двоичную систему счисления вам будет известно почему числа на выходе так странно округляются (23 бита мантиссы недостаточно, чтобы хранить всё число). Я задал вопрос на StackOverflow про такое округление. Вот что мне ответили:
Эти преобразования используют round-to-nearest mode, т.е. выбирается ближайшее число, которое представимо в нужном формате. В Вашем случае один кандидат меньше исходного числа на 82, другой больше на 46. Выбирается второй, т.к. он "ближе"
Ответ всего один и то мало понятный, но после кое-каких манипуляций я стал немного больше понимать "round-to-nearest mode"
Посмотрим на такой пример:
long a = Long.MAX_VALUE;
float b = (float) a;
long c = (long) b;
System.out.println(a); // вывод 9223372036854775807
System.out.println(b); // вывод 9.223372E18
System.out.println(c); // вывод 9223372036854775807
long aa = 1234567890;
float bb = (float) aa;
long cc = (long) bb;
System.out.println(aa); // вывод 1234567890
System.out.println(bb); // вывод 1.23456794E9
System.out.println(cc); // вывод 1234567936
Получается какой-то абсурд. Получается, что float b может хранить в себе число Long.MAX_VALUE без потерь, а число меньше (1234567890) не может!
Я попробовал сделать тоже самое, но с int:
Кому нужно объяснение, ловите...
По третьей задаче.
double d = (short) 2.50256e2d; //250
500e-3 //0.5
почему ?
для начала. что такое scientific notanion. если сильно упрощать, это запись иначе того, что мы обычно представляем как десятичные числа, но запись хитрая.
внимание на e2d и e-3 на конце записей.
здесь это в первом случае Е2 = 10^2, а д - double precision exponent. точность, если упрощать.
двойная (дабл)
что в итоге получаем ? в первом случае: 2.50256*100=250.256, дробная часть отбрасывается, в итоге 250.
во втором: 500e-3, обратите внимание на - (или минус 3). потому что это 10^(-3) или... 1/1000, или
500*0.0001, в итоге 0.5
Также как и с шортом выше,
short s = (short) 2.22; //2
Теперь. 150000 / 'd' - тут от чара берется значение https://unicode-table.com/en/ интовое, а именно 100, в итоге получается 1500
По второй задаче.
float f = (byte) 128.50;
здесь будет -128.0
почему ? вначале приводим к байту, отбрасываем дробное значение. выходит 128
128 не лезет в +127 (верхняя граница байта), потому...
128 % 256 = 128. 128 > 127 ? да. (если бы "нет", на этом бы остановились) 128 - 256 = -128
ну и в конце приводим обратно к флоату, добавляя дробную часть.
если не заморачиваться с вычислениями и принять как данность, будет усечение с "сюрпризом".
если интересно, можно разложить побитово и поиграться с значением, будет тот же результат, но возможно более поянтно.
Ндя, очень хотелось бы подробных разьяснений как решается последняя задача да как происходит приведение типов и их значений в этом случае. Да еще впервые вижу запись чисел через черточку
Подскажите, по какой причине при преобразовании целого числа 1234567890 во float получается 1.23456794E9, а не 1.23456789E9? Ведь знаков после запятой и в первом и во втором случае одинаковое количество и вроде как нет необходимости подрезать точность.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ