Преобразование типов
От: AH20  
Дата: 09.04.04 06:12
Оценка:
С железки приходят числа с плавающей точкой в паскалевском формате real (6 байт). Нужно преобразовать его в стандартное 8 байтовое сишное число. Как?

10.04.04 08:04: Перенесено модератором из 'C/C++' — ПК
Re: Преобразование типов
От: WolfHound  
Дата: 09.04.04 06:23
Оценка:
Здравствуйте, AH20, Вы писали:

AH>С железки приходят числа с плавающей точкой в паскалевском формате real (6 байт). Нужно преобразовать его в стандартное 8 байтовое сишное число. Как?

Ты уверен что 6 байт? Я просто такого формата не знаю. Знаю 4 байта, 8 байт и 10 байт. 6 байт не знаю.
... << RSDN@Home 1.1.3 beta 1 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[2]: Преобразование типов
От: LaptevVV Россия  
Дата: 09.04.04 06:27
Оценка: +1
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, AH20, Вы писали:


AH>>С железки приходят числа с плавающей точкой в паскалевском формате real (6 байт). Нужно преобразовать его в стандартное 8 байтовое сишное число. Как?

WH> Ты уверен что 6 байт? Я просто такого формата не знаю. Знаю 4 байта, 8 байт и 10 байт. 6 байт не знаю.
Да, именно 6 байт — это эмулируемый формат. Мы ла лабах со студентами смотрели.
ИМХО можно написать небольшую прогу на паскале, которая принимает real, а выдает double (понятно, что в single может не поместиться).
Иначе — ручками разобрать формат — на мантиссу и порядок и сформировать заново в double.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[2]: Преобразование типов
От: AH20  
Дата: 09.04.04 06:30
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, AH20, Вы писали:


AH>>С железки приходят числа с плавающей точкой в паскалевском формате real (6 байт). Нужно преобразовать его в стандартное 8 байтовое сишное число. Как?

WH> Ты уверен что 6 байт? Я просто такого формата не знаю. Знаю 4 байта, 8 байт и 10 байт. 6 байт не знаю.

Нашёл такую функцию преобразования в 4 байтовое число... С уменьшением точности. Хотелось бы этого избежать.


float RealToFloat(char *r) //r - ptr to 6 byte long array (real Pascal);
{
// 6 byte pascal real goes like this:
// byte #0:    bytes #1..5 (except MSB (left bit) in byte #5):        MSB (left bit) in byte #5:
// (exp+129)   (mantissa-1) as a binary fraction                    // sign (if==1 then minus)
// 8bit        39bit                                                // 1bit

// 4 byte float:
// MSB (left bit) of byte #0:    bits #1..8:        bits #9..31
// sign (if==1 then minus)        (exp+127)        (mantissa-1) as a binary fraction
// 1 bit                        8bit            23 bit

    union{
        long int s;    // 4 bytes;
        float    flt;
    }un;     

    unsigned char e;
    long int k;
    
    if( r[0]==0 )    un.flt = 0;
    else{
        e=r[0]-2;// the float exp is biased by 127, not 129 as in real
        memcpy(&un.s,&r[2],4); // mantissa (partial)

//ignore the first bit, set it to zero:
//after that, move the mantissa 8 bits to the right
        un.s=(un.s & 0x7FFFFFFF) >> 8;

        k=e;
// move exp 23 bits to the left 
        k <<= 23;
// get the sign from MSB of r[5] (left bit of right byte) and put it to the left of exp
        if( (r[5] & 0x80) )    k |= 0x80000000;//(r[5] & 0x80)==1 only if MSB of r[5]==1
        // k|=0x80000000 sets the first byte of k to 1 
        // k looks like this now: 
        // sign (1bit), then 23 bits (first 8 of this 23 contains exp+127, other contain zeroes)

        // after that, merge k to the un.s
        un.s |= k;
    }
    return un.flt;
}
Re[3]: Преобразование типов
От: LaptevVV Россия  
Дата: 09.04.04 06:34
Оценка:
Здравствуйте, AH20, Вы писали:

AH>Нашёл такую функцию преобразования в 4 байтовое число... С уменьшением точности. Хотелось бы этого избежать.

А почему именно на С писать надо?
Можно написать паскалевскую функцию, принимающую real, а выдающую результат double. А вызхвать из С паскалевскую прогу с одним параметром труда не составляет — модификатор pascal
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[4]: Преобразование типов
От: AH20  
Дата: 09.04.04 06:40
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>Здравствуйте, AH20, Вы писали:


AH>>Нашёл такую функцию преобразования в 4 байтовое число... С уменьшением точности. Хотелось бы этого избежать.

LVV>А почему именно на С писать надо?
LVV>Можно написать паскалевскую функцию, принимающую real, а выдающую результат double. А вызхвать из С паскалевскую прогу с одним параметром труда не составляет — модификатор pascal

Не могу найти информацию о побитовом представлении паскалевских типов.
Их double точно совпадает с сишным double? Имеется в виду длина мантиссы и т.д.
Re[5]: Преобразование типов
От: LaptevVV Россия  
Дата: 09.04.04 06:46
Оценка:
Здравствуйте, AH20, Вы писали:

AH>>>Нашёл такую функцию преобразования в 4 байтовое число... С уменьшением точности. Хотелось бы этого избежать.

LVV>>А почему именно на С писать надо?
LVV>>Можно написать паскалевскую функцию, принимающую real, а выдающую результат double. А вызхвать из С паскалевскую прогу с одним параметром труда не составляет — модификатор pascal

AH>Не могу найти информацию о побитовом представлении паскалевских типов.

AH>Их double точно совпадает с сишным double? Имеется в виду длина мантиссы и т.д.
Да
single = float, 4 байта
double = double, 8 байт
это работает НА ВСЕХ компиляторах, поскольку это стандарт IEEE реализованный в сопроцессоре Intel

extended = long double, 10 байт
Не везде выполняется, например Visual C++ long double = double.
а в Борландах — выполняется
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[6]: Преобразование типов
От: AH20  
Дата: 09.04.04 07:04
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>Да

LVV>single = float, 4 байта
LVV>double = double, 8 байт
LVV>это работает НА ВСЕХ компиляторах, поскольку это стандарт IEEE реализованный в сопроцессоре Intel

LVV>extended = long double, 10 байт

LVV>Не везде выполняется, например Visual C++ long double = double.
LVV>а в Борландах — выполняется

Пишу на VC++. Нашёл описание типов... В общем то майкрософтовский стандарт не совпадает с IEEE:

Microsoft 8 byte real (see note below)
63 56 55 54 0
.----------------------------------------------.
| 8bits |s|msb 52 bit mantissa lsb|
`----------------------------------------------'
| | `------------ mantissa
| `----------------------------- sign bit
`--------------------------- biased exponent (401h, see below)

IEEE 8 byte real
63 62 52 51 0
.-------------------------------------------------.
|s| 11 bits |msb 52 bit mantissa lsb|
`-------------------------------------------------'
| | `---------------- mantissa
| `-------------------------------- biased exponent (3FFh)
`------------------------------------- sign bit

Вот как оказывается всё непросто.
Re[7]: Преобразование типов
От: LaptevVV Россия  
Дата: 09.04.04 07:10
Оценка:
Здравствуйте, AH20, Вы писали:

LVV>>Да

LVV>>single = float, 4 байта
LVV>>double = double, 8 байт
LVV>>это работает НА ВСЕХ компиляторах, поскольку это стандарт IEEE реализованный в сопроцессоре Intel

LVV>>extended = long double, 10 байт

LVV>>Не везде выполняется, например Visual C++ long double = double.
LVV>>а в Борландах — выполняется

AH>Пишу на VC++. Нашёл описание типов... В общем то майкрософтовский стандарт не совпадает с IEEE:

AH>Вот как оказывается всё непросто.
Где такое описание?
double реализован аппаратно, поэтому микрософт не может ничего своего придумать.
В любой книжке по пентиуму про него написано.
Или это эмулируемый формат при отсутствии сопроцессора?
Или хдесь каким-то боком big-endian — little-endian?
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[7]: Преобразование типов
От: Андрей Тарасевич Беларусь  
Дата: 09.04.04 07:28
Оценка:
Здравствуйте, AH20, Вы писали:

AH>Здравствуйте, LaptevVV, Вы писали:


LVV>>Да

LVV>>single = float, 4 байта
LVV>>double = double, 8 байт
LVV>>это работает НА ВСЕХ компиляторах, поскольку это стандарт IEEE реализованный в сопроцессоре Intel

LVV>>extended = long double, 10 байт

LVV>>Не везде выполняется, например Visual C++ long double = double.
LVV>>а в Борландах — выполняется

AH>Пишу на VC++. Нашёл описание типов... В общем то майкрософтовский стандарт не совпадает с IEEE:


Ты, видимо, что-то путаешь. Нет никакого майкрософтовского стандарта. VC6 пользуется родными плавающими форматами x86.

Кстати, оффтопичный вопрос про плавающие форматы. Я, помнится, где-то читал, что на x86 в 10-тибайтовом плавающем формате мантисса должна явно содержать все разряды, включая ведущую единицу. Т.е. соглашение о неявной ведущей единице, имеющее место в случае 4-хбайтового и 8-мибайтового плавающих форматов, не распространяется на 10-тибайтовый формат. Во-первых, правда ли это? Во-вторых, если правда, то как это согласуется со стандартом IEEE? Допускает ли он такую возможность?
Best regards,
Андрей Тарасевич
Re[8]: Преобразование типов
От: AH20  
Дата: 09.04.04 07:33
Оценка:
Здесь описание...
Re[8]: Преобразование типов
От: LaptevVV Россия  
Дата: 09.04.04 07:43
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>Ты, видимо, что-то путаешь. Нет никакого майкрософтовского стандарта. VC6 пользуется родными плавающими форматами x86.


АТ>Кстати, оффтопичный вопрос про плавающие форматы. Я, помнится, где-то читал, что на x86 в 10-тибайтовом плавающем формате мантисса должна явно содержать все разряды, включая ведущую единицу. Т.е. соглашение о неявной ведущей единице, имеющее место в случае 4-хбайтового и 8-мибайтового плавающих форматов, не распространяется на 10-тибайтовый формат. Во-первых, правда ли это? Во-вторых, если правда, то как это согласуется со стандартом IEEE? Допускает ли он такую возможность?

1. Это действительно так. Сопроцессор интела имеет 8 10-байтных регистров, в которые можно загружать любые другие форматы сопроцессора. При этом неявная единица становится явной. Мантисса занимает 64 бита, порядок — 15 бит, первый бит — знак.
2. В стандарте IEE такого формата нет — есть только 32-битный и 64-битный. Его например, в Яве реализовали — там нет long double. Сопроцессор реализует оба этих формата в точности со стандартом, но операции выполняются на 80-битных регистрах.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[9]: Преобразование типов
От: LaptevVV Россия  
Дата: 09.04.04 07:47
Оценка:
Здравствуйте, AH20, Вы писали:

AH>Здесь описание...


Похоже. что это для фортрана, причем древнего, когда сопроцессора еще не было.
Возьми ЛЮБУЮ книгу по Пентюху — там форматы сопроцессора должны быть, Они именно такой вид в С++ и имеют.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[9]: Преобразование типов
От: LaptevVV Россия  
Дата: 09.04.04 07:50
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>2. В стандарте IEE такого формата нет — есть только 32-битный и 64-битный. Его например, в Яве реализовали — там нет long double. Сопроцессор реализует оба этих формата в точности со стандартом, но операции выполняются на 80-битных регистрах.

Возможно я ошибаюсь и такой стандарт есть, но я из книжки Таненбаума по операционным системам о стандарте IEEE сведения взял. Там формат 10 байт отсутствует.
В другой книжке Таненбаума "Организация ЭВМ" — тоже только два формата: 32 и 64 бита.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[10]: 80-битный формат
От: Reyst Россия  
Дата: 09.04.04 08:25
Оценка: 17 (2)
Здравствуйте, LaptevVV, Вы писали:

LVV>Здравствуйте, LaptevVV, Вы писали:


LVV>Там формат 10 байт отсутствует.

LVV>В другой книжке Таненбаума "Организация ЭВМ" — тоже только два формата: 32 и 64 бита.

Стандарт IEEE-754 предусматривает т.н. расширенные (extended) форматы (п. 3.3), на реализацию которых дается достаточная степень свободы.
80-битный формат x87 полностью соответствует требованиям стандарта к "Double-Extended format".
Представление ведущей единицы в мантиссе оговаривается как implementation-defined.

Подробнее — http://www.validlab.com/754R/standards/754xml.html, п.3.3;
книга "Numerical Computation Guide", Sun (нет под рукой...).
Все, что здесь сказано, может и будет использоваться против меня...
Re[7]: Преобразование типов
От: Fox007 Россия http://nalobin.ru
Дата: 09.04.04 08:41
Оценка:
Здравствуйте, AH20, Вы писали:

AH>Здравствуйте, LaptevVV, Вы писали:


AH>Пишу на VC++. Нашёл описание типов... В общем то майкрософтовский стандарт не совпадает с IEEE:


Странно... А на http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore/html/_core_why_floating_point_numbers_may_lose_precision.asp написано что

Microsoft Visual C++ uses IEEE floating-point format

Re: Преобразование типов
От: MBo  
Дата: 12.04.04 09:24
Оценка:
Здравствуйте, AH20, Вы писали:

AH>С железки приходят числа с плавающей точкой в паскалевском формате real (6 байт). Нужно преобразовать его в стандартное 8 байтовое сишное число. Как?



var
r:real48;
d:double;
begin
r:=123;
d:=r;
при этом вызывается функция из System

const
RealBias = 129;
ExtBias = $3FFF;


procedure _Real2Ext;//( val : Real ) : Extended;
asm
// -> EAX Pointer to value
// <- FST(0) Result

// the REAL data type has the following format:
// 8 bit exponent (bias 129), 39 bit fraction, 1 bit sign

MOV DH,[EAX+5] // isolate the sign bit
AND DH,80H
MOV DL,[EAX] // fetch exponent
TEST DL,DL // exponent zero means number is zero
JE @@zero

ADD DX,ExtBias-RealBias // adjust exponent bias

PUSH EDX // the exponent is at the highest address

MOV EDX,[EAX+2] // load high fraction part, set hidden bit
OR EDX,80000000H
PUSH EDX // push high fraction part

MOV DL,[EAX+1] // load remaining low byte of fraction
SHL EDX,24 // clear low 24 bits
PUSH EDX

FLD tbyte ptr [ESP] // pop result onto chip
ADD ESP,12

RET

@@zero:
FLDZ
RET
end;
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.