Thanks
Björn
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
What's the source/target for the values? PowerPC/ARM/Intelx86/Alpha/etc??
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
> 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
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.
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
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
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
(this code intentionally prevents compiler optimization)
(see also
http://www.csv.ica.uni-stuttgart.de/homes/ph/adakurs/stream2ph.adb
)
Peter Hermann
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.
Damien
> 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
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 ica...@csv.ica.uni-stuttgart.de
--Nobelstr.19 Raum 0.030, D-70550 Stuttgart Uni Hoechstleistungsrechnen
--http://www.csv.ica.uni-stuttgart.de/homes/ph/