[liba] isinf/isnan both work on double

Change-Id: I08e0c338e343a5357b91ed3a3f2e63db37efc983
This commit is contained in:
Romain Goyet
2017-08-03 14:51:00 +02:00
parent 878518b697
commit a1f1e2df6a
8 changed files with 47 additions and 10 deletions

View File

@@ -6,7 +6,9 @@ objs += $(addprefix liba/src/, \
assert.o \
errno.o \
ieee754.o \
isnand.o \
isnanf.o \
isinfd.o \
isinff.o \
malloc.o \
memcpy.o \

View File

@@ -13,13 +13,15 @@ LIBA_BEGIN_DECLS
/* The C99 standard requires isinf and isnan to be defined as macros that can
* handle arbitrary precision float numbers. The names of the functions called
* by those macros (depending on the argument size) are not standardized though.
* We're chosing isinff/isnanf for single-precision functions (which is the only
* case we're actually handling). */
* We're chosing isinff/isnanf for single-precision functions, and isinfd/isnand
* for double-precision functions. */
int isinff(float x);
#define isinf(x) isinff(x)
int isinfd(double d);
#define isinf(x) (sizeof(x) == sizeof(float) ? isinff(x) : isinfd(x))
int isnanf(float x);
#define isnan(x) isnanf(x)
int isnand(double x);
#define isnan(x) (sizeof(x) == sizeof(float) ? isnanf(x) : isnand(x))
float acosf(float x);
float acoshf(float x);

View File

@@ -3,7 +3,10 @@
#include <stdint.h>
uint32_t ieee754man(float x);
uint8_t ieee754exp(float x);
uint32_t ieee754man32(float x);
uint8_t ieee754exp32(float x);
uint64_t ieee754man64(double x);
uint16_t ieee754exp64(double x);
#endif

View File

@@ -1,6 +1,6 @@
#include <private/ieee754.h>
uint32_t ieee754man(float x) {
uint32_t ieee754man32(float x) {
union {
float f;
uint32_t i;
@@ -9,7 +9,7 @@ uint32_t ieee754man(float x) {
return (u.i & ((1<<23)-1));
}
uint8_t ieee754exp(float x) {
uint8_t ieee754exp32(float x) {
union {
float f;
uint32_t i;
@@ -17,3 +17,21 @@ uint8_t ieee754exp(float x) {
u.f = x;
return (u.i >> 23) & 0xFF;
}
uint64_t ieee754man64(double x) {
union {
double d;
uint64_t i;
} u;
u.d = x;
return (u.i & (((uint64_t)1<<52)-1));
}
uint16_t ieee754exp64(double x) {
union {
double d;
uint64_t i;
} u;
u.d = x;
return (uint16_t)((u.i >> 52) & 0x7FF);
}

6
liba/src/isinfd.c Normal file
View File

@@ -0,0 +1,6 @@
#include <math.h>
#include <private/ieee754.h>
int isinfd(double x) {
return (ieee754exp64(x) == 0x7FF && ieee754man64(x) == 0);
}

View File

@@ -2,5 +2,5 @@
#include <private/ieee754.h>
int isinff(float x) {
return (ieee754exp(x) == 0xFF && ieee754man(x) == 0);
return (ieee754exp32(x) == 0xFF && ieee754man32(x) == 0);
}

6
liba/src/isnand.c Normal file
View File

@@ -0,0 +1,6 @@
#include <math.h>
#include <private/ieee754.h>
int isnand(double x) {
return (ieee754exp64(x) == 0x7FF && ieee754man64(x) != 0);
}

View File

@@ -2,5 +2,5 @@
#include <private/ieee754.h>
int isnanf(float x) {
return (ieee754exp(x) == 0xFF && ieee754man(x) != 0);
return (ieee754exp32(x) == 0xFF && ieee754man32(x) != 0);
}