forked from GitHub/gf-core
added gu_out_u16be, gu_out_u64be and gu_out_f64be in libgu. The later is using gu_encode_double which is probably still wrong. Corrected gu_in_le and gu_in_f64be.
This commit is contained in:
@@ -41,3 +41,31 @@ gu_decode_double(uint64_t u)
|
|||||||
}
|
}
|
||||||
return sign ? copysign(ret, -1.0) : ret;
|
return sign ? copysign(ret, -1.0) : ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GU_INTERNAL uint64_t
|
||||||
|
gu_encode_double(double d)
|
||||||
|
{
|
||||||
|
int sign = (d < 0) ? 1 : 0;
|
||||||
|
int rawexp;
|
||||||
|
double mantissa;
|
||||||
|
|
||||||
|
switch (fpclassify(d)) {
|
||||||
|
case FP_NAN:
|
||||||
|
rawexp = 0x7ff;
|
||||||
|
mantissa = 1;
|
||||||
|
break;
|
||||||
|
case FP_INFINITE:
|
||||||
|
rawexp = 0x7ff;
|
||||||
|
mantissa = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mantissa = frexp(d, &rawexp);
|
||||||
|
rawexp += 1075;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t u = (((uint64_t) sign) << 63) |
|
||||||
|
((((uint64_t) rawexp) << 52) & 0x7ff) |
|
||||||
|
((uint64_t) mantissa);
|
||||||
|
|
||||||
|
return u;
|
||||||
|
}
|
||||||
|
|||||||
@@ -144,6 +144,7 @@ gu_decode_2c64(uint64_t u, GuExn* err)
|
|||||||
GU_INTERNAL_DECL double
|
GU_INTERNAL_DECL double
|
||||||
gu_decode_double(uint64_t u);
|
gu_decode_double(uint64_t u);
|
||||||
|
|
||||||
|
GU_INTERNAL_DECL uint64_t
|
||||||
|
gu_encode_double(double d);
|
||||||
|
|
||||||
#endif // GU_BITS_H_
|
#endif // GU_BITS_H_
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ gu_in_le(GuIn* in, GuExn* err, int n)
|
|||||||
uint8_t buf[8];
|
uint8_t buf[8];
|
||||||
gu_in_bytes(in, buf, n, err);
|
gu_in_bytes(in, buf, n, err);
|
||||||
uint64_t u = 0;
|
uint64_t u = 0;
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = n-1; i >= 0; i--) {
|
||||||
u = u << 8 | buf[i];
|
u = u << 8 | buf[i];
|
||||||
}
|
}
|
||||||
return u;
|
return u;
|
||||||
@@ -246,7 +246,7 @@ gu_in_f64le(GuIn* in, GuExn* err)
|
|||||||
GU_API double
|
GU_API double
|
||||||
gu_in_f64be(GuIn* in, GuExn* err)
|
gu_in_f64be(GuIn* in, GuExn* err)
|
||||||
{
|
{
|
||||||
return gu_decode_double(gu_in_u64le(in, err));
|
return gu_decode_double(gu_in_u64be(in, err));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include <gu/seq.h>
|
#include <gu/seq.h>
|
||||||
#include <gu/out.h>
|
#include <gu/out.h>
|
||||||
#include <gu/utf8.h>
|
#include <gu/utf8.h>
|
||||||
|
#include <gu/bits.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
@@ -168,8 +169,31 @@ gu_out_is_buffered(GuOut* out);
|
|||||||
extern inline bool
|
extern inline bool
|
||||||
gu_out_try_u8_(GuOut* restrict out, uint8_t u);
|
gu_out_try_u8_(GuOut* restrict out, uint8_t u);
|
||||||
|
|
||||||
|
GU_API void
|
||||||
|
gu_out_u16be(GuOut* out, uint16_t u, GuExn* err)
|
||||||
|
{
|
||||||
|
gu_out_u8(out, (u>>8) && 0xFF, err);
|
||||||
|
gu_out_u8(out, u && 0xFF, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
GU_API void
|
||||||
|
gu_out_u64be(GuOut* out, uint64_t u, GuExn* err)
|
||||||
|
{
|
||||||
|
gu_out_u8(out, (u>>56) && 0xFF, err);
|
||||||
|
gu_out_u8(out, (u>>48) && 0xFF, err);
|
||||||
|
gu_out_u8(out, (u>>40) && 0xFF, err);
|
||||||
|
gu_out_u8(out, (u>>32) && 0xFF, err);
|
||||||
|
gu_out_u8(out, (u>>24) && 0xFF, err);
|
||||||
|
gu_out_u8(out, (u>>16) && 0xFF, err);
|
||||||
|
gu_out_u8(out, (u>>8) && 0xFF, err);
|
||||||
|
gu_out_u8(out, u && 0xFF, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
GU_API void
|
||||||
|
gu_out_f64be(GuOut* out, double d, GuExn* err)
|
||||||
|
{
|
||||||
|
gu_out_u64be(out, gu_encode_double(d), err);
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct GuBufferedOutStream GuBufferedOutStream;
|
typedef struct GuBufferedOutStream GuBufferedOutStream;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user