comp.lang.ada
 help / color / mirror / Atom feed
* How to byte swap an IEEE Float?
@ 2005-06-28 13:53 Björn
  2005-06-28 15:06 ` Marius Amado Alves
                   ` (3 more replies)
  0 siblings, 4 replies; 16+ messages in thread
From: Björn @ 2005-06-28 13:53 UTC (permalink / raw)


I need to read some float values from file that have been written in
big-endian byte order from a c-program. The simple swapping procedure
that I have just interchanges the byte order of type IEEE_Float_32 to
get little-endian. The problem is that for some values (eg. 33.229000)
it is a "NaN" when doing IEEE_Float_32'Read and I get a constraint
error (invalid data) from stream_io when the value is read. How do I
get around this?

Thanks
Björn




^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: How to byte swap an IEEE Float?
  2005-06-28 13:53 How to byte swap an IEEE Float? Björn
@ 2005-06-28 15:06 ` Marius Amado Alves
  2005-06-28 15:55   ` Simon Wright
  2005-06-28 16:05 ` Martin Dowie
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 16+ messages in thread
From: Marius Amado Alves @ 2005-06-28 15:06 UTC (permalink / raw)
  To: comp.lang.ada


On 28 Jun 2005, at 14:53, Björn wrote:

> I need to read some float values from file that have been written in
> big-endian byte order from a c-program. The simple swapping procedure
> that I have just interchanges the byte order of type IEEE_Float_32 to
> get little-endian. The problem is that for some values (eg. 33.229000)
> it is a "NaN" when doing IEEE_Float_32'Read and I get a constraint
> error (invalid data) from stream_io when the value is read. How do I
> get around this?

Simple. Setup an array of bytes with the same representation of the 
float type (use representation clauses and pragma Pack). Read the array 
of bytes. Swap the bytes. Convert to the float type (use unchecked 
conversion).



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: How to byte swap an IEEE Float?
  2005-06-28 15:06 ` Marius Amado Alves
@ 2005-06-28 15:55   ` Simon Wright
  2005-06-28 16:59     ` Marius Amado Alves
  0 siblings, 1 reply; 16+ messages in thread
From: Simon Wright @ 2005-06-28 15:55 UTC (permalink / raw)


Marius Amado Alves <amado.alves@netcabo.pt> writes:

> On 28 Jun 2005, at 14:53, Bj�rn wrote:
>
>> I need to read some float values from file that have been written in
>> big-endian byte order from a c-program. The simple swapping procedure
>> that I have just interchanges the byte order of type IEEE_Float_32 to
>> get little-endian. The problem is that for some values (eg. 33.229000)
>> it is a "NaN" when doing IEEE_Float_32'Read and I get a constraint
>> error (invalid data) from stream_io when the value is read. How do I
>> get around this?
>
> Simple. Setup an array of bytes with the same representation of the
> float type (use representation clauses and pragma Pack). Read the
> array of bytes. Swap the bytes. Convert to the float type (use
> unchecked conversion).

Marius,

I think you mean 'of the same length as the float type'?

OP doesn't say what processor he gets the BE value from, but assuming
PowerPC you either get Float (4 bytes) for digits <= 6 or Long_Float
(8 bytes) for digits 7 .. 15.

On Intel hardware there's an 80-bit Long_Long_Float (digits 18).

-S



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: How to byte swap an IEEE Float?
  2005-06-28 13:53 How to byte swap an IEEE Float? Björn
  2005-06-28 15:06 ` Marius Amado Alves
@ 2005-06-28 16:05 ` Martin Dowie
  2005-06-28 23:35 ` Stephen Leake
  2005-06-29 20:10 ` Damien
  3 siblings, 0 replies; 16+ messages in thread
From: Martin Dowie @ 2005-06-28 16:05 UTC (permalink / raw)


Bj�rn wrote:
> I need to read some float values from file that have been written in
> big-endian byte order from a c-program. The simple swapping procedure
> that I have just interchanges the byte order of type IEEE_Float_32 to
> get little-endian. The problem is that for some values (eg. 33.229000)
> it is a "NaN" when doing IEEE_Float_32'Read and I get a constraint
> error (invalid data) from stream_io when the value is read. How do I
> get around this?

What's the source/target for the values? PowerPC/ARM/Intelx86/Alpha/etc??



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: How to byte swap an IEEE Float?
  2005-06-28 15:55   ` Simon Wright
@ 2005-06-28 16:59     ` Marius Amado Alves
  2005-06-28 20:43       ` Björn
  0 siblings, 1 reply; 16+ messages in thread
From: Marius Amado Alves @ 2005-06-28 16:59 UTC (permalink / raw)
  To: comp.lang.ada

On 28 Jun 2005, at 16:55, Simon Wright wrote:

> Marius Amado Alves <amado.alves@netcabo.pt> writes:
>
>> On 28 Jun 2005, at 14:53, Björn wrote:
>>
>>> I need to read some float values from file that have been written in
>>> big-endian byte order from a c-program. The simple swapping procedure
>>> that I have just interchanges the byte order of type IEEE_Float_32 to
>>> get little-endian. The problem is that for some values (eg. 
>>> 33.229000)
>>> it is a "NaN" when doing IEEE_Float_32'Read and I get a constraint
>>> error (invalid data) from stream_io when the value is read. How do I
>>> get around this?
>>
>> Simple. Setup an array of bytes with the same representation of the
>> float type (use representation clauses and pragma Pack). Read the
>> array of bytes. Swap the bytes. Convert to the float type (use
>> unchecked conversion).
>
> Marius,
>
> I think you mean 'of the same length as the float type'?
>
> OP doesn't say what processor he gets the BE value from, but assuming
> PowerPC you either get Float (4 bytes) for digits <= 6 or Long_Float
> (8 bytes) for digits 7 .. 15.
>
> On Intel hardware there's an 80-bit Long_Long_Float (digits 18).

Sure. You know, I meant representation = bits and bytes, implying same 
length. It seems the OP already has the float type (IEEE_Float_32), 
32-bit = 4-byte long, and the data are floats of this length, only 
different in byte order.

OP, if the data are of a different length, then you have to unchecked 
convert first to a float type of that length, and then normal convert 
to the final type (risking Constraint_Error).




^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: How to byte swap an IEEE Float?
  2005-06-28 16:59     ` Marius Amado Alves
@ 2005-06-28 20:43       ` Björn
  2005-06-29  0:13         ` Marius Amado Alves
  2005-06-30 19:14         ` Randy Brukardt
  0 siblings, 2 replies; 16+ messages in thread
From: Björn @ 2005-06-28 20:43 UTC (permalink / raw)


> Sure. You know, I meant representation = bits and bytes, implying same
> length. It seems the OP already has the float type (IEEE_Float_32),
> 32-bit = 4-byte long, and the data are floats of this length, only
> different in byte order.
>
> OP, if the data are of a different length, then you have to unchecked
> convert first to a float type of that length, and then normal convert
> to the final type (risking Constraint_Error).

All the data in the file are of 32 bits float so that should be ok.
The target for the values is at the moment x86 (although I do expect it
to work on PowerPC as well so I check System.Default_Bit_Order before
doing any byte swapping). My dirty workaround for the moment was to
read the data as a string. I was merly wondering which is the
normal/"best" way to deal with this, since I expect it to be a
fairly common task. A packed byte array does however seem like a much
better idea than handling it as a string.

Regards
Björn




^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: How to byte swap an IEEE Float?
  2005-06-28 13:53 How to byte swap an IEEE Float? Björn
  2005-06-28 15:06 ` Marius Amado Alves
  2005-06-28 16:05 ` Martin Dowie
@ 2005-06-28 23:35 ` Stephen Leake
  2005-06-29 10:00   ` Björn
  2005-06-29 20:10 ` Damien
  3 siblings, 1 reply; 16+ messages in thread
From: Stephen Leake @ 2005-06-28 23:35 UTC (permalink / raw)
  To: Björn; +Cc: comp.lang.ada

"Björn" <ssh9614@hotmail.com> writes:

> I need to read some float values from file that have been written in
> big-endian byte order from a c-program. 

See SAL.Network_Order.Gen_Scalar_64 at
http://www.toadmail.com/~ada_wizard/ada/sal.html for a convenient way
to do this.

> The simple swapping procedure that I have just interchanges the byte
> order of type IEEE_Float_32 to get little-endian. 

Ok.

> The problem is that for some values (eg. 33.229000) it is a "NaN"
> when doing IEEE_Float_32'Read and I get a constraint error (invalid
> data) from stream_io when the value is read. How do I get around
> this?

Hmm. Are you saying the original value is _not_ a NaN? If so, then
your swap implementation is faulty; try mine.

-- 
-- Stephe




^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: How to byte swap an IEEE Float?
  2005-06-28 20:43       ` Björn
@ 2005-06-29  0:13         ` Marius Amado Alves
  2005-06-30 19:14         ` Randy Brukardt
  1 sibling, 0 replies; 16+ messages in thread
From: Marius Amado Alves @ 2005-06-29  0:13 UTC (permalink / raw)
  To: comp.lang.ada


On 28 Jun 2005, at 21:43, Björn wrote:

>> Sure. You know, I meant representation = bits and bytes, implying same
>> length. It seems the OP already has the float type (IEEE_Float_32),
>> 32-bit = 4-byte long, and the data are floats of this length, only
>> different in byte order.
>>
>> OP, if the data are of a different length, then you have to unchecked
>> convert first to a float type of that length, and then normal convert
>> to the final type (risking Constraint_Error).
>
> All the data in the file are of 32 bits float so that should be ok.
> The target for the values is at the moment x86 (although I do expect it
> to work on PowerPC as well so I check System.Default_Bit_Order before
> doing any byte swapping). My dirty workaround for the moment was to
> read the data as a string. I was merly wondering which is the
> normal/"best" way to deal with this, since I expect it to be a
> fairly common task. A packed byte array does however seem like a much
> better idea than handling it as a string.

It is better. Because it's portable. Probably you got away with a 
String because on your system a String happens to be a packed array of 
bytes, but this is not guaranteed for all systems by the standard.




^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: How to byte swap an IEEE Float?
  2005-06-28 23:35 ` Stephen Leake
@ 2005-06-29 10:00   ` Björn
  2005-06-30  0:52     ` Stephen Leake
  0 siblings, 1 reply; 16+ messages in thread
From: Björn @ 2005-06-29 10:00 UTC (permalink / raw)


> See SAL.Network_Order.Gen_Scalar_64 at
> http://www.toadmail.com/~ada_wizard/ada/sal.html for a convenient way
> to do this.

Thanks! I will check it out.

> Hmm. Are you saying the original value is _not_ a NaN? If so, then
> your swap implementation is faulty; try mine.

No the original value _is_ a NaN when read as a float on x86 (the
subject on this thread was perhaps a bit misleading)

BR
Björn




^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: How to byte swap an IEEE Float?
  2005-06-28 13:53 How to byte swap an IEEE Float? Björn
                   ` (2 preceding siblings ...)
  2005-06-28 23:35 ` Stephen Leake
@ 2005-06-29 20:10 ` Damien
  2005-06-30 11:35   ` Peter Hermann
  3 siblings, 1 reply; 16+ messages in thread
From: Damien @ 2005-06-29 20:10 UTC (permalink / raw)


Bj�rn a �crit :
> I need to read some float values from file that have been written in
> big-endian byte order from a c-program. The simple swapping procedure
> that I have just interchanges the byte order of type IEEE_Float_32 to
> get little-endian. The problem is that for some values (eg. 33.229000)
> it is a "NaN" when doing IEEE_Float_32'Read and I get a constraint
> error (invalid data) from stream_io when the value is read. How do I
> get around this?
> 
I had to deal with byte swapping for floats and doubles between Intel 
and PPC. This was C++ and I discovered that swapping had to be done in a 
neutral form (byte array) before interpretation to float or double. 
Initialy I directly swapped floats and doubles, and for certain values 
some bits were changed.
So a function with such a signature should never be defined:
function Swap (X : Float) return Float;
It seems that all bit patterns can not be legal floats. I interpreted 
this as a normalisation of the float, but this is not sure at all.

So, to swap a float or a double X, do this :
1) convert X to a byte array Y (right size)
2) swap Y from host 1 format to network or archive format
3) send Y
4) read Y
5) swap Y from network or archive format to host 2 format
6) convert Y to X

I don't know if this is related to your problem, but it seems similar, 
and it may help.
It was C++, but those issues are language independent.

Damien Carbonne



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: How to byte swap an IEEE Float?
  2005-06-29 10:00   ` Björn
@ 2005-06-30  0:52     ` Stephen Leake
  2005-07-01  4:51       ` Simon Wright
  0 siblings, 1 reply; 16+ messages in thread
From: Stephen Leake @ 2005-06-30  0:52 UTC (permalink / raw)
  To: Björn; +Cc: comp.lang.ada

"Björn" <ssh9614@hotmail.com> writes:

>> See SAL.Network_Order.Gen_Scalar_64 at
>> http://www.toadmail.com/~ada_wizard/ada/sal.html for a convenient way
>> to do this.
>
> Thanks! I will check it out.
>
>> Hmm. Are you saying the original value is _not_ a NaN? If so, then
>> your swap implementation is faulty; try mine.
>
> No the original value _is_ a NaN when read as a float on x86 (the
> subject on this thread was perhaps a bit misleading)

Ok. So you have some code that generates a NaN, sends it over a
network or something, and then some Ada code wants to store it in a
Float value, still as a NaN.

Unchecked_Conversion should support that. I'm not quite clear what
will happen when you try to use the value or even assign the value;
you'll probably get Constraint_Error. You might try 'Valid.

The Ada model of floating point numbers does _not_ include NaN's, nor
infinities. 

-- 
-- Stephe




^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: How to byte swap an IEEE Float?
  2005-06-29 20:10 ` Damien
@ 2005-06-30 11:35   ` Peter Hermann
  2005-06-30 22:26     ` Damien
  0 siblings, 1 reply; 16+ messages in thread
From: Peter Hermann @ 2005-06-30 11:35 UTC (permalink / raw)


http://www.csv.ica.uni-stuttgart.de/homes/ph/adakurs/invert4bytes.adb

(this code intentionally prevents compiler optimization)

(see also
http://www.csv.ica.uni-stuttgart.de/homes/ph/adakurs/stream2ph.adb
)

Peter Hermann



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: How to byte swap an IEEE Float?
  2005-06-28 20:43       ` Björn
  2005-06-29  0:13         ` Marius Amado Alves
@ 2005-06-30 19:14         ` Randy Brukardt
  1 sibling, 0 replies; 16+ messages in thread
From: Randy Brukardt @ 2005-06-30 19:14 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1162 bytes --]

"Bj�rn" <ssh9614@hotmail.com> wrote in message
news:1119991404.697144.17980@g14g2000cwa.googlegroups.com...
...
> All the data in the file are of 32 bits float so that should be ok.
> The target for the values is at the moment x86 (although I do expect it
> to work on PowerPC as well so I check System.Default_Bit_Order before
> doing any byte swapping). My dirty workaround for the moment was to
> read the data as a string. I was merly wondering which is the
> normal/"best" way to deal with this, since I expect it to be a
> fairly common task. A packed byte array does however seem like a much
> better idea than handling it as a string.

I'd suggest using an array of stream elements for that (presuming that
they're the right size, they would be on almost all machines). That's
especially useful if you're reading the type as a stream in the first place,
because it would let you skip a copy.

If you absolutely have to have portability to any possible machine, then
you'd need to use your own type. But such a machine (such as the 36 bit
Unisys U2200) would probably have problems with 32-bit float values anyway.

                         Randy.






^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: How to byte swap an IEEE Float?
  2005-06-30 11:35   ` Peter Hermann
@ 2005-06-30 22:26     ` Damien
  2005-07-01  7:37       ` Peter Hermann
  0 siblings, 1 reply; 16+ messages in thread
From: Damien @ 2005-06-30 22:26 UTC (permalink / raw)


Peter Hermann a �crit :
> http://www.csv.ica.uni-stuttgart.de/homes/ph/adakurs/invert4bytes.adb
> 
> (this code intentionally prevents compiler optimization)
> 
> (see also
> http://www.csv.ica.uni-stuttgart.de/homes/ph/adakurs/stream2ph.adb
> )
Those examples only have integer values, for which a function like :
function Swap (X : Integer) return Integer;
does not raise any problem.
Any Integer or Modular type should not be a problem. It is only with 
floats that problems arise.

Damien



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: How to byte swap an IEEE Float?
  2005-06-30  0:52     ` Stephen Leake
@ 2005-07-01  4:51       ` Simon Wright
  0 siblings, 0 replies; 16+ messages in thread
From: Simon Wright @ 2005-07-01  4:51 UTC (permalink / raw)


Stephen Leake <stephen_leake@acm.org> writes:

> Ok. So you have some code that generates a NaN, sends it over a
> network or something, and then some Ada code wants to store it in a
> Float value, still as a NaN.

I understood that the problem was

   read a big-endian value from a file into a little-endian float
   byte-swap the float

Clearly you're at risk until the swap. Personally I'd read into an
array 1 .. 4 of Unsigned_8, swap, unchecked convert to Float ...

> Unchecked_Conversion should support that. I'm not quite clear what
> will happen when you try to use the value or even assign the value;
> you'll probably get Constraint_Error. You might try 'Valid.

> The Ada model of floating point numbers does _not_ include NaN's, nor
> infinities. 

You can generate them, but they are not 'Valid. With GNAT, you don't
get a Constraint_Error if you use type Float, but you do if you use

  subtype Checking_Float is Float range Float'First .. Float'Last;

-S



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: How to byte swap an IEEE Float?
  2005-06-30 22:26     ` Damien
@ 2005-07-01  7:37       ` Peter Hermann
  0 siblings, 0 replies; 16+ messages in thread
From: Peter Hermann @ 2005-07-01  7:37 UTC (permalink / raw)


Damien <damien.carbonne@free.fr> wrote:
> It is only with floats that problems arise.

of course. I just pointed to copyable code.

Conceivable are (e.g. GNAT-specific) mapped machine independent floating
point types for transfer purposes with a couple of predefined mantissa
and exponent sizes.
They may be more efficient than human readable text strings
(in any number base).

-- 
--Peter Hermann(49)0711-68587244 fax209 ica2ph@csv.ica.uni-stuttgart.de
--Nobelstr.19 Raum 0.030, D-70550 Stuttgart Uni Hoechstleistungsrechnen
--http://www.csv.ica.uni-stuttgart.de/homes/ph/



^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2005-07-01  7:37 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-06-28 13:53 How to byte swap an IEEE Float? Björn
2005-06-28 15:06 ` Marius Amado Alves
2005-06-28 15:55   ` Simon Wright
2005-06-28 16:59     ` Marius Amado Alves
2005-06-28 20:43       ` Björn
2005-06-29  0:13         ` Marius Amado Alves
2005-06-30 19:14         ` Randy Brukardt
2005-06-28 16:05 ` Martin Dowie
2005-06-28 23:35 ` Stephen Leake
2005-06-29 10:00   ` Björn
2005-06-30  0:52     ` Stephen Leake
2005-07-01  4:51       ` Simon Wright
2005-06-29 20:10 ` Damien
2005-06-30 11:35   ` Peter Hermann
2005-06-30 22:26     ` Damien
2005-07-01  7:37       ` Peter Hermann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox