Числа с плавающей точкой
, преобразовать в строку
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [152.53.39.118] |
|
|
Перед отправкой сообщения внимательно прочтите правила раздела!!!

Числа с плавающей точкой
, преобразовать в строку
|
Сообщ.
#1
,
|
|
|
|
Уважаемые программисты! Понимаю, что тема избита, но - если ввод и преобразование числа я ещё понял, то с выводом возникли проблемы. Вот как я принимаю число:
![]() ![]() format PE console include 'win32axp.inc' .data ns dd ? hout dd ? buffer db 51 dup (?) help db 'Usage: con_4islo.exe NUMBER',0 Retry db 'Program fails. Please, retry',0 num10 dt ? chislo dd ? ten dd 10 minus db ? status dw ? to4ka dd ? .code fuck: invoke GetStdHandle,STD_OUTPUT_HANDLE mov [hout],eax invoke GetCommandLine mov esi,eax cycle1: cmp byte [esi],20h je parameter cmp byte [esi],0Dh je najobka inc esi jmp cycle1 parameter: mov edi,buffer mov ecx,50 cycle2: inc esi mov al,byte [esi] cmp al,0Dh je konets mov byte [edi],al inc edi loop cycle2 konets: invoke lstrlen,buffer mov ecx,eax mov esi,buffer mov edi,esi add edi,ecx dec edi xor eax,eax finit fldz mov al,byte [esi] cmp al,2Dh je otric cycle3: mov al,byte [esi] inc esi cmp al,2Eh je drobnoe cmp al,2Ch je drobnoe sub al,30h jb retry cmp al,9 ja retry mov [chislo],eax fild [ten] fmulp st1,st fild [chislo] faddp st1,st loop cycle3 fldz jmp NoMore drobnoe: dec ecx xor eax,eax fldz cycle4: mov al,byte [edi] dec edi sub al,30h jb retry cmp al,9 ja retry mov [chislo],eax fild [chislo] faddp fild [ten] fdivp st1,st loop cycle4 NoMore: faddp st1,st xor eax,eax mov al,[minus] test al,al jz zagruz fchs zagruz: fstp tbyte [num10] exit: invoke ExitProcess,0 najobka: invoke WriteConsole,[hout],help,27,ns,NULL retry: invoke WriteConsole,[hout],Retry,28,ns,NULL jmp exit otric: mov [minus],1 dec ecx inc esi jmp cycle3 .end fuck И вот, я положил число в переменную num10 типа tbyte (это BCD формат, я так понял?) - я в принципе могу грузануть её обратно в стек FPU, провести необходимые арифметические операции, но как мне преобразовать это число в строку? Пожалуйста, не отсылайте меня к масмовским либам, а поясните хотя бы в общих словах алгоритм разбора BCD. Я, наверное, сам смогу вывести цифры в строку, но как определить десятичный порядок и правильно поставить разделитель-точку? Прошу вашей помощи |
|
Сообщ.
#2
,
|
|
|
|
Цитата adrax @ положил число в переменную num10 типа tbyte (это BCD формат, я так понял?) TBYTE - это не обязательно BCD Это просто 10-ть байт А уж как ты их будешь трактовать в программе, чисто твое дело.Цитата adrax @ но как определить десятичный порядок и правильно поставить разделитель-точку? Ничего определять не надо. Точка будет там, где ты этого захочешь. Попробую объяснить на самом простом (и быстром) способе - табличном. Ну во первых известно, что после запятой может быть от 0 до 17 знаков. Вот и заведи таблицу: ![]() ![]() ; 10 в степени N tenexp: dq 1.0E1, 1.0E2, 1.0E3, 1.0E4, 1.0E5, 1.0E6, 1.0E7, 1.0E8 dq 1.0E9, 1.0E10, 1.0E11, 1.0E12, 1.0E13, 1.0E14, 1.0E15, 1.0E16 dq 1.0E17 Т.е. массив состоит из заранее вычисленных коэффициентов 10 в степени от 1 до 17. Во вторых, поскольку при сохранении числа со стека сопроцессора в BCD происходит округление до целого, то прежде чем сохранять, его нужно масштабировать. А если по русски, то, к примеру, есть число 2222,3334444. Тебе нужно вывести его на экран (или куда там еще :-) в виде: 2222,333. Но поскольку при сохранении в BCD ты получишь число 2222, то необходимо еще до сохранения преобразовать его к виду 2222333,444. Это можно сделать умножив исходное число на 10^3 (поскольку нужно 3 числа после запятой, то и степень будет равна 3). Вот здесь то и пригодится массив tenexp А дальше при преобразовании BCD в строку просто вставляешь точку там где ее и заказывали. И все.Пробуй, если не получится - поможем |
|
Сообщ.
#3
,
|
|
|
|
Цитата adrax @ положил число в переменную num10 типа tbyte (это BCD формат, я так понял?) Смотря как "положил" ![]() fstp tbyte [num10] - сохраняет число в двоичном extended формате с плав.точкой fbstp tbyte [num10] - округляет число до целого и сохраняет в упакованном BCD-формате В первых (младших) 9 байтах хранятся 2*9=18 десятичных цифр числа - по 4 бита на цифру. Старший (знаковый) бит 10-го байта хранит знак числа. Для преобразования числа в строку с фикс.числом знаков после запятой нужно, как уже сказал AndNot, сначала умножить число на степень 10 в соответствии с требуемым числом знаков и выгрузить в BCD, а затем "ковыряться" с разбором этого BCD и формированием строки с учетом отбрасывания лидирующих нулей целой части и вставки разделительной точки на нужную позицию Цитата AndNot @ Точка будет там, где ты этого захочешь после запятой может быть от 0 до 17 знаков Не совсем так. Общее число знаков целой и дробной части не может быть больше 18-ти, иначе получишь переполнение. Поэтому если предварительно не анализировать порядок числа, то задавать большое число знаков после запятой не стоит |
|
Сообщ.
#4
,
|
|
|
|
Цитата leo @ Поэтому если предварительно не анализировать порядок числа, то задавать большое число знаков после запятой не стоит Это уже тонкости, и остается только добавить, что если не получается вывести в формате с плавающей точкой, то можно попытаться вывести в научной форме. Но там немного посложнее. |
|
Сообщ.
#5
,
|
|
|
|
Дело в том, что если выводить в экспоненциальном (научном формате), то я могу просто тупо перебить кусок готового кода, но меня интересует именно вывод в привычном виде - с точкой (ну или запятой)
leo Точно! Я ж не в BCD, я ж в extended!! Хотя всё равно не понимаю - как мне проанализировать тип extended, чтобы определить десятичный порядок и правильно пихнуть запятую... sprintf с %e не предлагайте, пжлст, лучше дайте пошаговое описание разбора extended-числа (про BCD нашёл статью "Арифметика с плавающей точкой", там рассказывается в формулах, и реализацию просто сделать на любом языке) - каков алгоритм? |
|
Сообщ.
#6
,
|
|
|
|
adrax, при выводе на экран и используют промежуточную BCD форму. А если extended напрямую анализировать, то сложность кода возрастет на порядок. Тебе это надо?
|