libstdc++: Apply modifications to our local copy of Ryu
This performs the following modifications to our local copy of Ryu in order to make it more readily usable for our std::to_chars implementation: * Remove all #includes * Remove copy_special_str routines * Adjust the exponent formatting to match printf * Remove some functions we're not going to use * Add an out-parameter to d2exp_buffered_n for the scientific exponent * Store the sign bit inside struct floating_decimal_[32|64] * Rename [df]2s_buffered_n and change their return type * Make generic_binary_to_decimal take the bit representation in parts libstdc++-v3/ChangeLog: * src/c++17/ryu/common.h, src/c++17/ryu/d2fixed.c, src/c++17/ryu/d2fixed_full_table.h, src/c++17/ryu/d2s.c, src/c++17/ryu/d2s_intrinsics.h, src/c++17/ryu/f2s.c, src/c++17/ryu/f2s_intrinsics.h, src/c++17/ryu/generic_128.c: Apply local modifications.
This commit is contained in:
parent
e3f0eaa282
commit
5033506993
8 changed files with 45 additions and 236 deletions
|
@ -17,9 +17,6 @@
|
|||
#ifndef RYU_COMMON_H
|
||||
#define RYU_COMMON_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(_M_IX86) || defined(_M_ARM)
|
||||
#define RYU_32_BIT_PLATFORM
|
||||
|
@ -83,22 +80,6 @@ static inline uint32_t log10Pow5(const int32_t e) {
|
|||
return (((uint32_t) e) * 732923) >> 20;
|
||||
}
|
||||
|
||||
static inline int copy_special_str(char * const result, const bool sign, const bool exponent, const bool mantissa) {
|
||||
if (mantissa) {
|
||||
memcpy(result, "NaN", 3);
|
||||
return 3;
|
||||
}
|
||||
if (sign) {
|
||||
result[0] = '-';
|
||||
}
|
||||
if (exponent) {
|
||||
memcpy(result + sign, "Infinity", 8);
|
||||
return sign + 8;
|
||||
}
|
||||
memcpy(result + sign, "0E0", 3);
|
||||
return sign + 3;
|
||||
}
|
||||
|
||||
static inline uint32_t float_to_bits(const float f) {
|
||||
uint32_t bits = 0;
|
||||
memcpy(&bits, &f, sizeof(float));
|
||||
|
|
|
@ -23,23 +23,11 @@
|
|||
//
|
||||
// -DRYU_AVOID_UINT128 Avoid using uint128_t. Slower, depending on your compiler.
|
||||
|
||||
#include "ryu/ryu.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef RYU_DEBUG
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include "ryu/common.h"
|
||||
#include "ryu/digit_table.h"
|
||||
#include "ryu/d2fixed_full_table.h"
|
||||
#include "ryu/d2s_intrinsics.h"
|
||||
|
||||
#define DOUBLE_MANTISSA_BITS 52
|
||||
#define DOUBLE_EXPONENT_BITS 11
|
||||
|
@ -328,33 +316,6 @@ static inline uint32_t lengthForIndex(const uint32_t idx) {
|
|||
return (log10Pow2(16 * (int32_t) idx) + 1 + 16 + 8) / 9;
|
||||
}
|
||||
|
||||
static inline int copy_special_str_printf(char* const result, const bool sign, const uint64_t mantissa) {
|
||||
#if defined(_MSC_VER)
|
||||
// TODO: Check that -nan is expected output on Windows.
|
||||
if (sign) {
|
||||
result[0] = '-';
|
||||
}
|
||||
if (mantissa) {
|
||||
if (mantissa < (1ull << (DOUBLE_MANTISSA_BITS - 1))) {
|
||||
memcpy(result + sign, "nan(snan)", 9);
|
||||
return sign + 9;
|
||||
}
|
||||
memcpy(result + sign, "nan", 3);
|
||||
return sign + 3;
|
||||
}
|
||||
#else
|
||||
if (mantissa) {
|
||||
memcpy(result, "nan", 3);
|
||||
return 3;
|
||||
}
|
||||
if (sign) {
|
||||
result[0] = '-';
|
||||
}
|
||||
#endif
|
||||
memcpy(result + sign, "Infinity", 8);
|
||||
return sign + 8;
|
||||
}
|
||||
|
||||
int d2fixed_buffered_n(double d, uint32_t precision, char* result) {
|
||||
const uint64_t bits = double_to_bits(d);
|
||||
#ifdef RYU_DEBUG
|
||||
|
@ -372,20 +333,10 @@ int d2fixed_buffered_n(double d, uint32_t precision, char* result) {
|
|||
|
||||
// Case distinction; exit early for the easy cases.
|
||||
if (ieeeExponent == ((1u << DOUBLE_EXPONENT_BITS) - 1u)) {
|
||||
return copy_special_str_printf(result, ieeeSign, ieeeMantissa);
|
||||
__builtin_abort();
|
||||
}
|
||||
if (ieeeExponent == 0 && ieeeMantissa == 0) {
|
||||
int index = 0;
|
||||
if (ieeeSign) {
|
||||
result[index++] = '-';
|
||||
}
|
||||
result[index++] = '0';
|
||||
if (precision > 0) {
|
||||
result[index++] = '.';
|
||||
memset(result + index, '0', precision);
|
||||
index += precision;
|
||||
}
|
||||
return index;
|
||||
__builtin_abort();
|
||||
}
|
||||
|
||||
int32_t e2;
|
||||
|
@ -549,21 +500,9 @@ int d2fixed_buffered_n(double d, uint32_t precision, char* result) {
|
|||
return index;
|
||||
}
|
||||
|
||||
void d2fixed_buffered(double d, uint32_t precision, char* result) {
|
||||
const int len = d2fixed_buffered_n(d, precision, result);
|
||||
result[len] = '\0';
|
||||
}
|
||||
|
||||
char* d2fixed(double d, uint32_t precision) {
|
||||
char* const buffer = (char*)malloc(2000);
|
||||
const int index = d2fixed_buffered_n(d, precision, buffer);
|
||||
buffer[index] = '\0';
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int d2exp_buffered_n(double d, uint32_t precision, char* result) {
|
||||
int d2exp_buffered_n(double d, uint32_t precision, char* result, int* exp_out) {
|
||||
const uint64_t bits = double_to_bits(d);
|
||||
#ifdef RYU_DEBUG
|
||||
printf("IN=");
|
||||
|
@ -580,22 +519,10 @@ int d2exp_buffered_n(double d, uint32_t precision, char* result) {
|
|||
|
||||
// Case distinction; exit early for the easy cases.
|
||||
if (ieeeExponent == ((1u << DOUBLE_EXPONENT_BITS) - 1u)) {
|
||||
return copy_special_str_printf(result, ieeeSign, ieeeMantissa);
|
||||
__builtin_abort();
|
||||
}
|
||||
if (ieeeExponent == 0 && ieeeMantissa == 0) {
|
||||
int index = 0;
|
||||
if (ieeeSign) {
|
||||
result[index++] = '-';
|
||||
}
|
||||
result[index++] = '0';
|
||||
if (precision > 0) {
|
||||
result[index++] = '.';
|
||||
memset(result + index, '0', precision);
|
||||
index += precision;
|
||||
}
|
||||
memcpy(result + index, "e+00", 4);
|
||||
index += 4;
|
||||
return index;
|
||||
__builtin_abort();
|
||||
}
|
||||
|
||||
int32_t e2;
|
||||
|
@ -785,6 +712,9 @@ int d2exp_buffered_n(double d, uint32_t precision, char* result) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (exp_out) {
|
||||
*exp_out = exp;
|
||||
}
|
||||
result[index++] = 'e';
|
||||
if (exp < 0) {
|
||||
result[index++] = '-';
|
||||
|
@ -805,15 +735,3 @@ int d2exp_buffered_n(double d, uint32_t precision, char* result) {
|
|||
|
||||
return index;
|
||||
}
|
||||
|
||||
void d2exp_buffered(double d, uint32_t precision, char* result) {
|
||||
const int len = d2exp_buffered_n(d, precision, result);
|
||||
result[len] = '\0';
|
||||
}
|
||||
|
||||
char* d2exp(double d, uint32_t precision) {
|
||||
char* const buffer = (char*)malloc(2000);
|
||||
const int index = d2exp_buffered_n(d, precision, buffer);
|
||||
buffer[index] = '\0';
|
||||
return buffer;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#ifndef RYU_D2FIXED_FULL_TABLE_H
|
||||
#define RYU_D2FIXED_FULL_TABLE_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define TABLE_SIZE 64
|
||||
|
||||
|
|
|
@ -27,28 +27,15 @@
|
|||
// size by about 10x (only one case, and only double) at the cost of some
|
||||
// performance. Currently requires MSVC intrinsics.
|
||||
|
||||
#include "ryu/ryu.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef RYU_DEBUG
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include "ryu/common.h"
|
||||
#include "ryu/digit_table.h"
|
||||
#include "ryu/d2s_intrinsics.h"
|
||||
|
||||
// Include either the small or the full lookup tables depending on the mode.
|
||||
#if defined(RYU_OPTIMIZE_SIZE)
|
||||
#include "ryu/d2s_small_table.h"
|
||||
#else
|
||||
#include "ryu/d2s_full_table.h"
|
||||
#endif
|
||||
|
||||
#define DOUBLE_MANTISSA_BITS 52
|
||||
|
@ -86,9 +73,10 @@ typedef struct floating_decimal_64 {
|
|||
// Decimal exponent's range is -324 to 308
|
||||
// inclusive, and can fit in a short if needed.
|
||||
int32_t exponent;
|
||||
bool sign;
|
||||
} floating_decimal_64;
|
||||
|
||||
static inline floating_decimal_64 d2d(const uint64_t ieeeMantissa, const uint32_t ieeeExponent) {
|
||||
static inline floating_decimal_64 d2d(const uint64_t ieeeMantissa, const uint32_t ieeeExponent, const bool ieeeSign) {
|
||||
int32_t e2;
|
||||
uint64_t m2;
|
||||
if (ieeeExponent == 0) {
|
||||
|
@ -308,13 +296,14 @@ static inline floating_decimal_64 d2d(const uint64_t ieeeMantissa, const uint32_
|
|||
floating_decimal_64 fd;
|
||||
fd.exponent = exp;
|
||||
fd.mantissa = output;
|
||||
fd.sign = ieeeSign;
|
||||
return fd;
|
||||
}
|
||||
|
||||
static inline int to_chars(const floating_decimal_64 v, const bool sign, char* const result) {
|
||||
static inline int to_chars(const floating_decimal_64 v, char* const result) {
|
||||
// Step 5: Print the decimal representation.
|
||||
int index = 0;
|
||||
if (sign) {
|
||||
if (v.sign) {
|
||||
result[index++] = '-';
|
||||
}
|
||||
|
||||
|
@ -397,29 +386,28 @@ static inline int to_chars(const floating_decimal_64 v, const bool sign, char* c
|
|||
}
|
||||
|
||||
// Print the exponent.
|
||||
result[index++] = 'E';
|
||||
result[index++] = 'e';
|
||||
int32_t exp = v.exponent + (int32_t) olength - 1;
|
||||
if (exp < 0) {
|
||||
result[index++] = '-';
|
||||
exp = -exp;
|
||||
}
|
||||
} else
|
||||
result[index++] = '+';
|
||||
|
||||
if (exp >= 100) {
|
||||
const int32_t c = exp % 10;
|
||||
memcpy(result + index, DIGIT_TABLE + 2 * (exp / 10), 2);
|
||||
result[index + 2] = (char) ('0' + c);
|
||||
index += 3;
|
||||
} else if (exp >= 10) {
|
||||
} else {
|
||||
memcpy(result + index, DIGIT_TABLE + 2 * exp, 2);
|
||||
index += 2;
|
||||
} else {
|
||||
result[index++] = (char) ('0' + exp);
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
static inline bool d2d_small_int(const uint64_t ieeeMantissa, const uint32_t ieeeExponent,
|
||||
static inline bool d2d_small_int(const uint64_t ieeeMantissa, const uint32_t ieeeExponent, const bool ieeeSign,
|
||||
floating_decimal_64* const v) {
|
||||
const uint64_t m2 = (1ull << DOUBLE_MANTISSA_BITS) | ieeeMantissa;
|
||||
const int32_t e2 = (int32_t) ieeeExponent - DOUBLE_BIAS - DOUBLE_MANTISSA_BITS;
|
||||
|
@ -448,10 +436,11 @@ static inline bool d2d_small_int(const uint64_t ieeeMantissa, const uint32_t iee
|
|||
// Note: since 2^53 < 10^16, there is no need to adjust decimalLength17().
|
||||
v->mantissa = m2 >> -e2;
|
||||
v->exponent = 0;
|
||||
v->sign = ieeeSign;
|
||||
return true;
|
||||
}
|
||||
|
||||
int d2s_buffered_n(double f, char* result) {
|
||||
floating_decimal_64 floating_to_fd64(double f) {
|
||||
// Step 1: Decode the floating-point number, and unify normalized and subnormal cases.
|
||||
const uint64_t bits = double_to_bits(f);
|
||||
|
||||
|
@ -469,11 +458,11 @@ int d2s_buffered_n(double f, char* result) {
|
|||
const uint32_t ieeeExponent = (uint32_t) ((bits >> DOUBLE_MANTISSA_BITS) & ((1u << DOUBLE_EXPONENT_BITS) - 1));
|
||||
// Case distinction; exit early for the easy cases.
|
||||
if (ieeeExponent == ((1u << DOUBLE_EXPONENT_BITS) - 1u) || (ieeeExponent == 0 && ieeeMantissa == 0)) {
|
||||
return copy_special_str(result, ieeeSign, ieeeExponent, ieeeMantissa);
|
||||
__builtin_abort();
|
||||
}
|
||||
|
||||
floating_decimal_64 v;
|
||||
const bool isSmallInt = d2d_small_int(ieeeMantissa, ieeeExponent, &v);
|
||||
const bool isSmallInt = d2d_small_int(ieeeMantissa, ieeeExponent, ieeeSign, &v);
|
||||
if (isSmallInt) {
|
||||
// For small integers in the range [1, 2^53), v.mantissa might contain trailing (decimal) zeros.
|
||||
// For scientific notation we need to move these zeros into the exponent.
|
||||
|
@ -489,21 +478,8 @@ int d2s_buffered_n(double f, char* result) {
|
|||
++v.exponent;
|
||||
}
|
||||
} else {
|
||||
v = d2d(ieeeMantissa, ieeeExponent);
|
||||
v = d2d(ieeeMantissa, ieeeExponent, ieeeSign);
|
||||
}
|
||||
|
||||
return to_chars(v, ieeeSign, result);
|
||||
}
|
||||
|
||||
void d2s_buffered(double f, char* result) {
|
||||
const int index = d2s_buffered_n(f, result);
|
||||
|
||||
// Terminate the string.
|
||||
result[index] = '\0';
|
||||
}
|
||||
|
||||
char* d2s(double f) {
|
||||
char* const result = (char*) malloc(25);
|
||||
d2s_buffered(f, result);
|
||||
return result;
|
||||
return v;
|
||||
}
|
||||
|
|
|
@ -17,11 +17,8 @@
|
|||
#ifndef RYU_D2S_INTRINSICS_H
|
||||
#define RYU_D2S_INTRINSICS_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Defines RYU_32_BIT_PLATFORM if applicable.
|
||||
#include "ryu/common.h"
|
||||
|
||||
// ABSL avoids uint128_t on Win32 even if __SIZEOF_INT128__ is defined.
|
||||
// Let's do the same for now.
|
||||
|
@ -37,7 +34,6 @@ typedef __uint128_t uint128_t;
|
|||
|
||||
#if defined(HAS_64_BIT_INTRINSICS)
|
||||
|
||||
#include <intrin.h>
|
||||
|
||||
static inline uint64_t umul128(const uint64_t a, const uint64_t b, uint64_t* const productHi) {
|
||||
return _umul128(a, b, productHi);
|
||||
|
|
|
@ -18,22 +18,11 @@
|
|||
// Runtime compiler options:
|
||||
// -DRYU_DEBUG Generate verbose debugging output to stdout.
|
||||
|
||||
#include "ryu/ryu.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef RYU_DEBUG
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include "ryu/common.h"
|
||||
#include "ryu/f2s_intrinsics.h"
|
||||
#include "ryu/digit_table.h"
|
||||
|
||||
#define FLOAT_MANTISSA_BITS 23
|
||||
#define FLOAT_EXPONENT_BITS 8
|
||||
|
@ -45,9 +34,10 @@ typedef struct floating_decimal_32 {
|
|||
// Decimal exponent's range is -45 to 38
|
||||
// inclusive, and can fit in a short if needed.
|
||||
int32_t exponent;
|
||||
bool sign;
|
||||
} floating_decimal_32;
|
||||
|
||||
static inline floating_decimal_32 f2d(const uint32_t ieeeMantissa, const uint32_t ieeeExponent) {
|
||||
static inline floating_decimal_32 f2d(const uint32_t ieeeMantissa, const uint32_t ieeeExponent, const bool ieeeSign) {
|
||||
int32_t e2;
|
||||
uint32_t m2;
|
||||
if (ieeeExponent == 0) {
|
||||
|
@ -224,13 +214,14 @@ static inline floating_decimal_32 f2d(const uint32_t ieeeMantissa, const uint32_
|
|||
floating_decimal_32 fd;
|
||||
fd.exponent = exp;
|
||||
fd.mantissa = output;
|
||||
fd.sign = ieeeSign;
|
||||
return fd;
|
||||
}
|
||||
|
||||
static inline int to_chars(const floating_decimal_32 v, const bool sign, char* const result) {
|
||||
static inline int to_chars(const floating_decimal_32 v, char* const result) {
|
||||
// Step 5: Print the decimal representation.
|
||||
int index = 0;
|
||||
if (sign) {
|
||||
if (v.sign) {
|
||||
result[index++] = '-';
|
||||
}
|
||||
|
||||
|
@ -288,24 +279,22 @@ static inline int to_chars(const floating_decimal_32 v, const bool sign, char* c
|
|||
}
|
||||
|
||||
// Print the exponent.
|
||||
result[index++] = 'E';
|
||||
result[index++] = 'e';
|
||||
int32_t exp = v.exponent + (int32_t) olength - 1;
|
||||
if (exp < 0) {
|
||||
result[index++] = '-';
|
||||
exp = -exp;
|
||||
} else {
|
||||
result[index++] = '+';
|
||||
}
|
||||
|
||||
if (exp >= 10) {
|
||||
memcpy(result + index, DIGIT_TABLE + 2 * exp, 2);
|
||||
index += 2;
|
||||
} else {
|
||||
result[index++] = (char) ('0' + exp);
|
||||
}
|
||||
memcpy(result + index, DIGIT_TABLE + 2 * exp, 2);
|
||||
index += 2;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
int f2s_buffered_n(float f, char* result) {
|
||||
floating_decimal_32 floating_to_fd32(float f) {
|
||||
// Step 1: Decode the floating-point number, and unify normalized and subnormal cases.
|
||||
const uint32_t bits = float_to_bits(f);
|
||||
|
||||
|
@ -324,22 +313,9 @@ int f2s_buffered_n(float f, char* result) {
|
|||
|
||||
// Case distinction; exit early for the easy cases.
|
||||
if (ieeeExponent == ((1u << FLOAT_EXPONENT_BITS) - 1u) || (ieeeExponent == 0 && ieeeMantissa == 0)) {
|
||||
return copy_special_str(result, ieeeSign, ieeeExponent, ieeeMantissa);
|
||||
__builtin_abort();
|
||||
}
|
||||
|
||||
const floating_decimal_32 v = f2d(ieeeMantissa, ieeeExponent);
|
||||
return to_chars(v, ieeeSign, result);
|
||||
}
|
||||
|
||||
void f2s_buffered(float f, char* result) {
|
||||
const int index = f2s_buffered_n(f, result);
|
||||
|
||||
// Terminate the string.
|
||||
result[index] = '\0';
|
||||
}
|
||||
|
||||
char* f2s(float f) {
|
||||
char* const result = (char*) malloc(16);
|
||||
f2s_buffered(f, result);
|
||||
return result;
|
||||
const floating_decimal_32 v = f2d(ieeeMantissa, ieeeExponent, ieeeSign);
|
||||
return v;
|
||||
}
|
||||
|
|
|
@ -18,18 +18,14 @@
|
|||
#define RYU_F2S_INTRINSICS_H
|
||||
|
||||
// Defines RYU_32_BIT_PLATFORM if applicable.
|
||||
#include "ryu/common.h"
|
||||
|
||||
#if defined(RYU_FLOAT_FULL_TABLE)
|
||||
|
||||
#include "ryu/f2s_full_table.h"
|
||||
|
||||
#else
|
||||
|
||||
#if defined(RYU_OPTIMIZE_SIZE)
|
||||
#include "ryu/d2s_small_table.h"
|
||||
#else
|
||||
#include "ryu/d2s_full_table.h"
|
||||
#endif
|
||||
#define FLOAT_POW5_INV_BITCOUNT (DOUBLE_POW5_INV_BITCOUNT - 64)
|
||||
#define FLOAT_POW5_BITCOUNT (DOUBLE_POW5_BITCOUNT - 64)
|
||||
|
|
|
@ -37,42 +37,9 @@ static char* s(uint128_t v) {
|
|||
|
||||
#define ONE ((uint128_t) 1)
|
||||
|
||||
#define FLOAT_MANTISSA_BITS 23
|
||||
#define FLOAT_EXPONENT_BITS 8
|
||||
|
||||
struct floating_decimal_128 float_to_fd128(float f) {
|
||||
uint32_t bits = 0;
|
||||
memcpy(&bits, &f, sizeof(float));
|
||||
return generic_binary_to_decimal(bits, FLOAT_MANTISSA_BITS, FLOAT_EXPONENT_BITS, false);
|
||||
}
|
||||
|
||||
#define DOUBLE_MANTISSA_BITS 52
|
||||
#define DOUBLE_EXPONENT_BITS 11
|
||||
|
||||
struct floating_decimal_128 double_to_fd128(double d) {
|
||||
uint64_t bits = 0;
|
||||
memcpy(&bits, &d, sizeof(double));
|
||||
return generic_binary_to_decimal(bits, DOUBLE_MANTISSA_BITS, DOUBLE_EXPONENT_BITS, false);
|
||||
}
|
||||
|
||||
#define LONG_DOUBLE_MANTISSA_BITS 64
|
||||
#define LONG_DOUBLE_EXPONENT_BITS 15
|
||||
|
||||
struct floating_decimal_128 long_double_to_fd128(long double d) {
|
||||
uint128_t bits = 0;
|
||||
memcpy(&bits, &d, sizeof(long double));
|
||||
#ifdef RYU_DEBUG
|
||||
// For some odd reason, this ends up with noise in the top 48 bits. We can
|
||||
// clear out those bits with the following line; this is not required, the
|
||||
// conversion routine should ignore those bits, but the debug output can be
|
||||
// confusing if they aren't 0s.
|
||||
bits &= (ONE << 80) - 1;
|
||||
#endif
|
||||
return generic_binary_to_decimal(bits, LONG_DOUBLE_MANTISSA_BITS, LONG_DOUBLE_EXPONENT_BITS, true);
|
||||
}
|
||||
|
||||
struct floating_decimal_128 generic_binary_to_decimal(
|
||||
const uint128_t bits, const uint32_t mantissaBits, const uint32_t exponentBits, const bool explicitLeadingBit) {
|
||||
const uint128_t ieeeMantissa, const uint32_t ieeeExponent, const bool ieeeSign,
|
||||
const uint32_t mantissaBits, const uint32_t exponentBits, const bool explicitLeadingBit) {
|
||||
#ifdef RYU_DEBUG
|
||||
printf("IN=");
|
||||
for (int32_t bit = 127; bit >= 0; --bit) {
|
||||
|
@ -82,9 +49,6 @@ struct floating_decimal_128 generic_binary_to_decimal(
|
|||
#endif
|
||||
|
||||
const uint32_t bias = (1u << (exponentBits - 1)) - 1;
|
||||
const bool ieeeSign = ((bits >> (mantissaBits + exponentBits)) & 1) != 0;
|
||||
const uint128_t ieeeMantissa = bits & ((ONE << mantissaBits) - 1);
|
||||
const uint32_t ieeeExponent = (uint32_t) ((bits >> mantissaBits) & ((ONE << exponentBits) - 1u));
|
||||
|
||||
if (ieeeExponent == 0 && ieeeMantissa == 0) {
|
||||
struct floating_decimal_128 fd;
|
||||
|
@ -320,14 +284,17 @@ int generic_to_chars(const struct floating_decimal_128 v, char* const result) {
|
|||
}
|
||||
|
||||
// Print the exponent.
|
||||
result[index++] = 'E';
|
||||
result[index++] = 'e';
|
||||
int32_t exp = v.exponent + olength - 1;
|
||||
if (exp < 0) {
|
||||
result[index++] = '-';
|
||||
exp = -exp;
|
||||
}
|
||||
} else
|
||||
result[index++] = '+';
|
||||
|
||||
uint32_t elength = decimalLength(exp);
|
||||
if (elength == 1)
|
||||
++elength;
|
||||
for (uint32_t i = 0; i < elength; ++i) {
|
||||
const uint32_t c = exp % 10;
|
||||
exp /= 10;
|
||||
|
|
Loading…
Add table
Reference in a new issue