Re: Convert float to its corresponding bytes?

2019-01-29 Thread nour
This is really a particluar need, Can it be done otherwise, i.e. reject the 
proposed solution and look again to the problem, because, although it was done, 
it does not make such sens for the "Why?" question.


Re: Convert float to its corresponding bytes?

2019-01-26 Thread doofenstein
the reason I thought this way, was because I translated the Nim code in my head 
to C, to something like that: 


void flt2arr(double x, uint8_t[] result) {
  for(int i = 0; i < 8; i++)
result[i] = (uint8_t*) + i;
}


Run

But as @araq said, this is not what the output of the Nim compiler is


Re: Convert float to its corresponding bytes?

2019-01-26 Thread zevv
Does it also use an union when compiling to C++?


Re: Convert float to its corresponding bytes?

2019-01-26 Thread e
In C99 (ISO/IEC 9899:1999 6.5/7; the exact same wording is used in ISO/IEC 
9899:2011 ยง6.5/7)

> An object shall have its stored value accessed only by an lvalue expression 
> that has one of the following types ... a character type.

The meaning of "a character type" here includes unsigned char, which is also 
uint8. So, making some assumptions about the Nim code generator, both 
approaches are well defined in C.


Re: Convert float to its corresponding bytes?

2019-01-26 Thread zevv
The following should also be safe, this translates to a memcpy() at the C 
level. This may seem like overkill, but the C compiler should recognize the use 
of memcpy for type punning and optimize it away and generate a register to 
register move.


proc flt2arr(f: var float64, a: var array[8, uint8]) =
  assert sizeof(a) == sizeof(f)
  copyMem(addr a[0], addr f, sizeof f)

proc arr2flt(a: var array[8, uint8], f: var float64) =
  assert sizeof(a) == sizeof(f)
  copyMem(addr f, addr a[0], sizeof f)


Run


Re: Convert float to its corresponding bytes?

2019-01-26 Thread doofenstein
afaik atleast in C there's no "safe" way to do it. The method presented by @e 
works in most situations, but breaks strict aliasing (a poiner of one type may 
not be casted to a pointer of an incompatible type).

The usual safer way, in C is by using a union: 


type
Uint8ToFloat64 {.union.} = object
f: float64
i: array[8, uint8]

proc floatToInts(f: float64): array[8, uint8] =
var convert: Uint8ToFloat64
convert.f = f
convert.i
proc intsToFloat(i: array[8, uint8]): float64 =
var convert: Uint8ToFloat64
convert.i = i
convert.f

doAssert intsToFloat(floatToInts(-42.0)) == -42.0


Run


Re: Convert float to its corresponding bytes?

2019-01-26 Thread lqdev
Thank you very much, this is exactly what I need. I was thinking about using 
casts but wasn't really sure if it's safe.


Re: Convert float to its corresponding bytes?

2019-01-26 Thread e
Here's a little program demonstrating conversion functions:


import parseutils, os

func flt2arr (x: float64) : array[0..7, uint8] =
result = cast[array[0..7, uint8]](x)

func arr2flt (a: array[0..7, uint8]) : float64 =
result = cast[float64](a)

when isMainModule:
let params = commandLineParams()
var flt : float64
discard parseFloat(params[0], flt)
let ary = flt2arr(flt)
for u in ary:
echo(u)
let arr : array[0..7, uint8]
 = [ary[0]+1, ary[1], ary[2], ary[3], ary[4], ary[5], ary[6], ary[7]]
echo(arr2flt(arr))

Run