IEEE754 float

Тема в разделе "WASM.BEGINNERS", создана пользователем NetDemon, 24 май 2007.

  1. NetDemon

    NetDemon New Member

    Публикаций:
    0
    Регистрация:
    24 апр 2007
    Сообщения:
    22
    с теорией IEEE 754 вроде все понятно...

    но на практике возникают затупы - как перевести побитово?
    пример:

    число "-11151.47" float, single precision....
    hex: C62E3DDE
    двоичное: 11000110 00101110 00111101 11011110

    знак= 1, тобишь "-"
    exp= 140-127= 13
    мантисса получается 1,01011100011110111011110

    судя по всему сдвигаем вправо запятую- 10101110001111 получаем 11151
    остается - 0111011110... и как из этого получить остаток .47?

    другой пример:

    число "0.7584" float, single precision....
    hex: 3D9B5200
    двоичное: 00111101 10011011 01010010 00000000

    знак= 0, тобишь +
    exp= 123-127=-4
    мантисса получается 1,100110110101001000000000

    судя по всему нужно сначала сдвинуть запятую на 4 знака... но куда?
    если влево, то нули подставлять?
    и как получить после этого 10чное число?


    ЗЫ. Помогите плиз разобраться с этими примерами!!!!
     
  2. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Ты и сюда успел запостить ;)
    Неверной дорогой идете, товарисч. Тебе нужна дробная часть в десятичном виде (по отрицательным степенями 10-и), а ты пытаешься анализировать дробную часть в двоичном виде (по отрицательным степеням 2). А получить десятичное число с фиксированным числом знаков после запятой легко - умножить число на соответсвующую степень 10-и, округлить до целого, преобразовать в строку и вставить разделительную точку на нужную позицию (см.аналогичный вопрос)
     
  3. NetDemon

    NetDemon New Member

    Публикаций:
    0
    Регистрация:
    24 апр 2007
    Сообщения:
    22
    Спасибо, любезная моя Екатер...эээ
    любезный leo
    Я не пытался написать функцию "с нуля" испытывая "юношеский задор", как ты уже писал....
    мне просто интересно было разобраться как устроен формат float
    :)
     
  4. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Ты же говоришь "с теорией IEEE 754 вроде все понятно...", значит дело не в формате, а в "как получить после этого 10чное число?"
    Вся разница между десятичным и двоичным представлением заключается в том, что в первом случае имеем разложение числа по степеням 10, а во втором по степеням 2. Например, десятичное число 2.5 = 2*10^0 + 5*10^(-1), а в двоичном виде с фикс.запятой оно будет 10.1 = 1*2^1+0*2^0+1*2^(-1), при этом нормализованная мантисса = 1.01 и порядок = (+1).
    А число 0.25 = 1/4 в фикс.двоич.формате = 0.01, мантисса = 1.0, порядок = (-2)
     
  5. NetDemon

    NetDemon New Member

    Публикаций:
    0
    Регистрация:
    24 апр 2007
    Сообщения:
    22
    Эх... в том и дело, что "вроде", а на практике тупняк :dntknw:
    В любом случае спасибо.... не каждый разжует простые вещи....
    Ответь пожалуста на следущий вопрос:
    при операциях с числами IEEE754 возникают различные неточности,
    какие именно и как их можно обойти?
    одно я вроде понял нельзя делать a==b, нужно чтото вроде abs (a-b) < 0,000001
     
  6. W4FhLF

    W4FhLF New Member

    Публикаций:
    0
    Регистрация:
    3 дек 2006
    Сообщения:
    1.050
    http://basicproduction.nm.ru/articles/bpdblvb.htm
     
  7. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    NetDemon
    +,-,* как правило точные, погрешности обязательно возникают в трансцендентных коммандах sin, cos и т.п.
    Узнать что произошло округление результата можно по флагу PE в SW ("липкий" бит).
    А в общем используй 80бит там где ооочень критична накапливающаяся погрешность, 64 бит для промежуточных вычислений и 32бит для окончательного представления результата и будет тебе счастье :)
    А "нельзя делать a==b, нужно чтото вроде abs (a-b) < 0,000001" это только если тебе нужна меньшая точность, чем обеспечивают выбранные тобой 80, 64, 32 бита ;), впрочем в реальных технических вычисления и при моделировании физических процессов как раз и приходится ограничивать точность таким приёмом, дабы избавиться от кучи знаков после запятой, когда точность измерения входных\выходных параметров в лучшем случае 5-10%. Особенно полезен этот приём при итерациях до достижения заданной точности.
     
  8. NetDemon

    NetDemon New Member

    Публикаций:
    0
    Регистрация:
    24 апр 2007
    Сообщения:
    22
    Допустим взять матрицы трансформации- элементы 32 бита,
    получается что их надо конвертить? или 32 обеспечивают достаточную точность
    в данном случае?
     
  9. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    NetDemon
    Зависит от задачи - если трансформация нужна только перед отрисовкой объекта на экране то 32 бит вполне достаточно, а вот если крутишь объект, сохраняешь его в памяти, затем опять крутишь, опять сохраняешь и так много раз, то матрицы следует рассчитать (а не просто преобразовать ;) поточнее.
     
  10. NetDemon

    NetDemon New Member

    Публикаций:
    0
    Регистрация:
    24 апр 2007
    Сообщения:
    22
    Y_Mur
    а где можно почитать поподробней насчет применения таких чисел в 3Д графике?
     
  11. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Принцип:
    универсальный не зависимо от области приенения, а про нюансы точности вообще здесь
     
  12. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Y_Mur
    Не совсем так. Источниками погрешностей\неточностей являются
    1) ограниченное число двоичных разрядов мантиссы числа
    2) ограниченная точность вычислений
    Ограничение на число разрядов нужно учитывать при выборе типа констант, хотя этим часто пренебрегают, а потом удивляются - см.например Проблема с FLD или твой же опус "мах = 1.0E17 и DWORD сойдёт" - если число выглядит простым и круглым в десятичной системе, это не значит, что оно будет таким же в двоичной ;))
    Операции +,-,* не "как правило точные", а максимально точные независимо от установки PC (precision control). Но их точность все равно ограничена 64 битами мантиссы, т.е. младший бит по любому округляется, если результат не влезает в 64 бита. А вот точность деления, корня и трансцендентых операций зависит от установки PC. При PC = single или double точность ограничена, но вычисления производятся быстрее, а при PC = extended (по умолчанию после finit) точность трансцендентных операций также равна 64 битам. Кстати неучет PC тоже вызывает массу вопросов и недоумений (см. например Прикольный баг Olly с FPU)

    Тут нужно пояснить - смотря как производится сравнение. Если все вычисления и сравнение написаны на асме с использованием регистров FPU без выгрузки в память, то сравнение на диапазон обязательны, т.к. ошибки в младших разрядах 64-битной мантиссы практически неизбежны. Но если после вычислений сохранить a и b формате float или double, то эти мизерные погрешности "исчезают" (см.тут или тут)и после этого уже можно сравнивать a == b

    PS: одним словом тема весьма избитая и поиск как всегда рулит ;))