Двач, объясни пожалуйста дауну, как перевести float (4 байта) в double (8 байт)? Я раньше думал, что можно просто 4 нулевых байта добавить и будет норм, а оказалось нихуя. Единственное, что я понял, что первый бит в записи означает знак (0=+, 1=-), остальное какая-то ебаная магия, какие-то непонятные цифры, хз че происходит помогите
>>254727321 >А нахуя, если компьютер это делает аппаратно? У меня он делает какую-то хуйню. Например есть float 1.73 Я перевожу в double и получаю 1.7299999935683924 вроде такой хуйни.
>>254727690 > В отличие от чисел с фиксированной запятой, сетка чисел, которые способна отобразить арифметика с плавающей запятой, неравномерна: она более густая для чисел с малыми порядками и более редкая — для чисел с большими порядками.
>>254727713 ДА ЧТ ЗА НАРКОМАНИЯ БЛЯДЬ? Как одно число превращается в другое? Вот было у меня 2 яблока, я перекинул его в другую корзину и стало 1 яблоко. Куда еще одно делось?
>>254725792 (OP) float это же не целые числа с запятой. или я чего то не понимаю? что тебе мешает блять взять табоицу байтов(или как ткм она называется), и перевести блять это в байты?
>>254727875 Ещё одно обозначает знак, представь запись числа один: 01, +1, -1. Аж целых три варианта для двух символов, неизвестно какой реализовали у тебя.
>Я раньше думал, что можно просто 4 нулевых байта добавить и будет норм, а оказалось нихуя. Это сработало бы для целочисленных типов, но для чисел с плавающей точкой дополнительные биты не только расширяют диапазон, но и увеличивают "точность" (т.е. кол-во знаков после запятой)
>>254725792 (OP) Кому вообще эти плавающие точки нужны кроме учёных и астрономов? Игры/видео/аудио/нейросети прекрасно работают на целочисленной арифметике.
>>254728753 Блядь, в чем сложность-то, выше уже есть ссылки на википедию, где половина кода написана: Рабираешь побитовыми операциями свой 32-битный флоат на знак/порядок/мантиссу, собираешь из них 64-битный double.
>>254729376 >собираешь из них 64-битный double. Как, блядь? Я понимаю, где знак-порядок-мантисса, но как их превратить в 64-битный формат непонятно нихуя.
>>254729553 Там в википедии есть "Общий шаблон для побитового доступа" (для флоата), тебе нужно понять, как это работает и написать такой же для дабла.
>>254729780 >"Общий шаблон для побитового доступа" (для флоата), тебе нужно понять, как это работает Ебаный рот, я в курсе, что такое побитовый доступ. Вот тебе на пикрелейтеде, одно и то же число. 1) показатель для Float 10000111; 2) показатель для Double 10000000111; Каким ебаным хуем первое превращается во второе?
>>254730242 А этого можно "избежать", если сначала кастить в строку. Знаешь почему так происходит? Потому что изначально флоат хранит больше данных, чем отображает. То есть потери информации не происходит.
>>254730053 Перебираешь справа налево, если нулики до конца -- тыришь циферку и пишешь её в строку, затем достаёшь свой дабл и тыкаешь её туда, не забывая нарисовать запятую.
>>254730362 >Перебираешь справа налево, если нулики до конца Чего? Если нулики до конца, то число = 0, до какого конца то? > тыришь циферку и пишешь её в строку Какую циферку? Куда её писать, о чем ты вообще.
>>254730912 Округление работает только если я представляю число в десятичной записи типа 0.0033. А если в экспоненциальной, то пишет хуету вроде 3.299993584383573e-3. Мне надо именно экспоненциальная форма.
>>254731105 Это крайне долбоёбская задача. В таком случае советую округлять через форматирование строк. Но для вычислений округление уже не использовать, потому что ну ёбаны в рот, какого хуя-то блядь.
>>254731232 Так ему сразу сказали делать через строки, а он хочет не решение получить, а перед кем-то отчитаться видимо. В реальности этим не занимаются, главное чтоб работало, а как - не твоя проблема.
>>254731238 Это не я хочу, а так надо по условию задачи. >>254731232 Как это округлять через форматирование строк? Ты имеешь в виду просто отбрасывать лишнее или что? В любом случае мне надо производить расчеты с числом, значит придется обратно переводить, это уже потеря точности.
>>254731573 Нет, это ты хочешь и всё. Была бы задача - ты бы решил просто представив всё как целое число, в меру требуемой точности, а на выходе дорисовал бы что надо. Заказчик всё равно не увидит, а результат будет. А вот если это понты всякие, вроде задачи для учебника, то тут надо смотреть мануалы и отгадывать что именно от тебя хотят увидеть.
>>254731368 Иногда важно знать, как работает, но выводить в гуй значения в не человекочитаемых форматах - чистый долбоебизм.
>>254731573 >Ты имеешь в виду просто отбрасывать лишнее или что? Примерно так округление и работает. >В любом случае мне надо производить расчеты с числом Ты тупой? Ты тупой. Зачем тебе проводить расчёты с округлённым числом, где информация в любом случае будет теряться, когда у тебя есть оригинальное число. Не округлённое. В гуй выводи хоть залупу конскую, хоть строки. Для вычислений это не важно. А вычисления производи над наиболее полными данными.
>>254731977 Читаемый формат делается подстановкой нужных символов в нужном месте, я это говорю как чел который сделал эмулятор машины тьюринга и тайно пользовался ею вместо готовых процедур, ибо весело.
>>254731846 >Нет, это ты хочешь и всё. Была бы задача - ты бы решил просто представив всё как целое число, в меру требуемой точности, а на выходе дорисовал бы что надо. Заказчик всё равно не увидит, а результат будет. Заказчик хочет увидеть число в экспоненциальной форме, т.е. N x 10^M. >>254731977 >Примерно так округление и работает. Че ты несешь? Так работает округление только в меньшую сторону. >Зачем тебе проводить расчёты с округлённым числом, где информация в любом случае будет теряться, когда у тебя есть оригинальное число. Оригинальное число хуевое. Вот например есть число 1e-3, которое поступает в виде флоат 4 байта. Если я перевожу его в дабл, оно превращается в 9.999999353812e-4. Превращение в строку превратит это в явное говно. Мне нужно именно 1e-3, а не 9.9e-4.
>>254732287 Берёшь десятичное написание, тыришь циферки и записываешь так как просят. Если точность не проверяют - можешь ходь рандомный диапазон после запятой задавать.
>>254732485 Это и есть цивилизованный способ, может и есть супер-пупер функция чтоб делать так как ты сказал, но внутри может быть та же самая история. Более того скажу - комп именно так и работает, он не воспринимает нашу чушь и считает всё целочисленным, а уже потом расценивает некоторые числа не так как другие. Познай природу компьютера, будь естественным, кодь как индус.
>>254733026 Всё считает, физически у него есть только ничего и единички, а чтоб ты смог увидеть что-то после запятой или с минусом - приходится часть чисел расценивать не как часть числа, а как знаковую и дополнительную области.
>>254733137 Нет, для компьютера есть массивы битов. Это не то же самое, что единички и нолики, нолики и единички - это отображение для людей. Так вот если массив битов, который воспринимается компьютером, как число с плавающей запятой. И расчёты над этими числами выполняются на соответствующих аппаратных блоках, например FP32.
+1 степень, это ясно. степень 1013 - это что? Это в десятичном выражении или как? Откуда это число взялось? Почему основание степени - двойка? Что такое 1.024? Я так понимаю это нужно разложить снизу вверх? Как они 0.001 разложили на это: +1 0.00097656250000000000 1.024?
>>254733340 Внезапно ни запятой, ни массива компьютер не видит. И лишь интерпретируя единички, их наличие в заданном месте, он даёт нам то что мы считаем плавающей запятой.
>>254727875 Оно записывается в двоичной системе, поэтому не всегда возможно записать точное значение. Например, 11.62510 в двоичной представляется как 1011.1012, и соответственно оно может быть записано точно как в double, так и во float. В то же время, например, 1.210 в двоичной системе счисления может быть записано только в виде бесконечной периодической дроби: 0.001100110011...2 = 0.(0011)2. Кроме того, количество цифр после (и перед) запятой конечное, поэтому даже те числа, которые в двоичной системе имеют конечное число цифр после запятой, не всегда могут быть записаны точно даже в long double (10 байт).
>>254733580 Массивы битов это выдуманная людьми условность, так как они не способны смириться с тем что компьютер это супер быстрый Абу который считает всё палочками.
>>254733697 Не такой уж и быстрый. Если его заставить считать именно единичками и ноликами, то будет раз в десять медленнее, чем операции над массивами битов на специализированных вычислительных блоках. Сейчас вот в видимокартах пошла мода на половинную точность, потому что тогда массив битов, приходящих в блок короче и вычислять получается быстрее.
>>254733978 Пойми, вычислительные блоки это Абу с покрашенными палочками: он считает единички, а ты их интерпретируешь не так как Абу. Но реальность такова что это единички, даже если ты завёл для этого отдельного Абу и посадил его в отдельный обезьянник.
>>254733611 >В то же время, например, 1.2 в двоичной системе счисления может быть записано только в виде бесконечной периодической дроби: Почему нельзя записать 1.10?
>>254733611 >Кроме того, количество цифр после (и перед) запятой конечное, поэтому даже те числа, которые в двоичной системе имеют конечное число цифр после запятой, не всегда могут быть записаны точно даже в long double (10 байт). Хуйня какая-то, любое двоичное число переводится в десятичное. Вот есть же 0 = 0 1 = 1 10 = 2 11 = 3 100 = 4 101 = 5 и так далее. Почему нельзя точно записать?
>>254733396 > 1e-3 Это десятичная экспоненциальная запись. Один умножить на десять в минус третьей. Сохранить ее без потери точности в двоичной экспоненциальной записи нельзя.
>+1 степень, это ясно. +1 это знак, положительное
>степень 1013 - это что? Это в десятичном выражении или как? Это десятичное беззнаковое, просто как если бы биты означали целое неотрицательное число (0-2047). Но показатели бывают отрицательные (-1023 - +1024), поэтому из него надо вычесть 1023 (получится минус десять).
> 0.0009765625 Это два в степени минус десять
> Что такое 1.024 Мантисса.
> Откуда это число взялось? В момент float x = 1e-3; происходит конверсия.
> Почему основание степени - двойка Коротко, по стандарту. Стандарт такой потому что так считать эффективнее.
>>254734318 >+1 это знак, положительное Да, у меня башка уже кружится от этого гавна >(получится минус десять) Почему нам нужно именно минус десять? >Это два в степени минус десять Это я понял, только откуда здесь минус десять то высралось. >Мантисса. Что мантисса? Мантисса это 1 в числе 1e-3. Что за 1.024? >Коротко, по стандарту. Стандарт такой потому что так считать эффективнее. Вообще ничего непонятно.
>>254734583 Единица есть сигнал, нет - нет. Это не бит, а единица, так как комп не умеет читать нули. Но благодаря интерпретации мы можем учитывать отсутствие единиц в определённых местах и так привязываем одни единички - к другим.
>>254734638 > Что мантисса? Мантисса это 1 в числе 1e-3. Что за 1.024? В десятичной записи этого числа мантисса это 1. В двоичной - 1.024 (а показатель - минус десять). Просто перевели из десятичной системы счисления в двоичную, потому что по стандарту/определению float и double записываются в двоичной. В процессе перевода точность потерялась.
>>254735157 >В исходниках оно хранится текстом: Спрошу по-другому, мне в программу приходит 4 байта, являющихся числом с плавающей точкой Я никак не могу изменить формат получения данных, НЕ текст, а именно 4 байта. Мне нужно превратить их в 8 байт для обработки.
>>254735518 Ну чел, нельзя просто взять и в двух словах на двачах объяснить, как устроены числа с плавающей запятой. Особенно тому, кто не знает про системы счисления. Продолжай разбираться, гугли, читай всякие статьи на хабре на эту тему. В какой-то момент дойдет. Для начала осознай, что ответа на вопрос, как это сделать, не будет пока ты не поймешь, как это устроено.
>>254737358 Я примерно понял, не могу понять другую вещь, почему нельзя округлить число до определенной точности? Ну то есть если я отбрасываю в мантиссе даже последний бит, то получаю огромное неадекватное число. Как правильно округлять то?
>>254738026 Я имел ввиду, приведи число полностью. Это 8 бит, которые в начале, после знака? Это не мантисса, а показатель степени. Мантисса это последние 23 бита.
>>254738298 >Это не мантисса, а показатель степени. Мантисса это последние 23 бита. Я знаю, я просто пример привел. >Я имел ввиду, приведи число полностью. Ну вот например пикрелейтед. Последнюю "с" поменял на 0. Мантисса превратилась в огромный пиздец. Вопрос как именно сделать так, чтобы было 0.001.
>>254738748 Вот смотри, ты хочешь представить в двоичной системе число 1/1000, которое в десятичной системе выражается точно как 0.001 = 1 × 10-3. В двоичной системе счисления это не выражается конечной дробью: 0.00110 = 0.00000110001...2. Поэтому это число просто нельзя представить точно ни в float, ни в double.
>>254739352 Блядь, так он тебе и вывел в читаемом нахуй формате, ебать. Ебаный отладчик округлил ебучую дробь, потому что блядское отклонение очень маленькое, что тебе непонятно?
>>254739514 Тебе же вроде надо было преобразовать float в double, не? Или ты не ОП? Как округлить при выводе - совсем отдельный вопрос. Что конкретно тебе надо сделать?
>>254739732 Если тебе надо преобразовать float в double, тебе не надо ничего округлять. Тебе нужно просто корректно скопировать мантиссу, порядок и знак.
ладно, челики, так и быть, напишу float в double в языке си приводится неявно, это присваивающее приведение, вам не требуется явного преобразования (double) второе, с вероятностью 95% на современных платформах будет использоваться явная машинная команда преобразования, например под x86-64 это будет ассемблерная команда cvtss2sd, будет задействован сопроцессор - модуль операций с плавающей точкой
>>254741663 но если опу очень хочеться с учебной целью сделать такое приведение руками, то вот подсказка: нужно использовать struct с union внутри для того чтобы получить плоское представление float и double в памяти, а потом уже таким образом получив доступ к внутреннему представлению вещественных чисел, написать алгоритм преобразования ручками внутреннее представление float и double в x86-64 легко гуглиться, как и алгоритм преобразования вообще, если подобные задания тебе дают в вузике, то это хороший вуз и хороший препод
>>254727875 Тип с плавающей точкой не может хранить непрерывное множество чисел, поэтому некоторые значения могут быть представлены в нём только как приближения к желаемым. Поэтому, плавающую арифметику категорически нельзя использовать, например, для денежных величин, где погрешность в принципе недопустима.
>>254741253 Неправильно копируешь, значит. Учти еще, что там бывают особые случаи, когда порядок минимальный (денормализованная форма записи числа) или максимальный (частные случаи: бесконечность, не-число). Разберись подробнее. Вот тебе пример:
>>254743748 Для денормализованных чисел типа float (E = 0) все по-другому, потому что они, в отличие от нормализованных, имеют вид 0,M × 2-126. Денормализованные числа типа double, соответственно: 0,M' × 2-1022. Поэтому денормализованный float придется преобразовать в нормализованный double (E' > 0), который имеет вид 1,M' × 2E' - 1023, то есть эту неявную единичку нужно в таком случае брать в расчет.
>>254727514 >Например есть float 1.73 >Я перевожу в double и получаю 1.7299999935683924 вроде такой хуйни. - Сколько программистов нужно, чтобы вкрутить лампочку? - 1.9946938293545, но это приемлемая точность.
>>254741977 >Поэтому, плавающую арифметику категорически нельзя использовать, например, для денежных величин, где погрешность в принципе недопустима. Раз уж подняли такую тему, как на ЦПП делать арифметику с фиксированной точкой с минимальным количеством костылей? коллеги по разработке звукового движка кидают в меня тухлыми помидорами за использование uint, который надо сдвигать, но продолжают им пользоваться