Skip to content

Commit

Permalink
Fixes mpaland#105: Making all potentially-value-altering conversions …
Browse files Browse the repository at this point in the history
…explicit, and some additional minor changes:

* Now compiling with the `-Wconversion` warning flag when using clang or gcc.
* In all cases noticed by gcc in which an implicit conversion was made which could change the converted value - have changed the conversion to be explicit.
* Renamed: `get_sign()` -> `get_sign_bit()` (so as to clarify the return value is either 0 or 1, not -1 or 1).
* Added explanatory comment for the `double_components` structure.
  • Loading branch information
eyalroz committed Feb 21, 2022
1 parent 919ee0a commit 957cedd
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 8 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ if (CMAKE_C_COMPILER_ID STREQUAL "MSVC")
target_compile_options(printf PRIVATE /W4)
elseif (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR
CMAKE_C_COMPILER_ID STREQUAL "Clang")
target_compile_options(printf PRIVATE -Wall -Wextra -pedantic)
target_compile_options(printf PRIVATE -Wall -Wextra -pedantic -Wconversion)
endif()

if (BUILD_TESTS)
Expand Down
18 changes: 11 additions & 7 deletions src/printf/printf.c
Original file line number Diff line number Diff line change
Expand Up @@ -261,10 +261,10 @@ static inline double_with_bit_access get_bit_access(double x)
return dwba;
}

static inline int get_sign(double x)
static inline int get_sign_bit(double x)
{
// The sign is stored in the highest bit
return get_bit_access(x).U >> (DOUBLE_SIZE_IN_BITS - 1);
return (int) (get_bit_access(x).U >> (DOUBLE_SIZE_IN_BITS - 1));
}

static inline int get_exp2(double_with_bit_access x)
Expand Down Expand Up @@ -358,7 +358,7 @@ static inline output_gadget_t discarding_gadget()
static inline output_gadget_t buffer_gadget(char* buffer, size_t buffer_size)
{
printf_size_t usable_buffer_size = (buffer_size > PRINTF_MAX_POSSIBLE_BUFFER_SIZE) ?
PRINTF_MAX_POSSIBLE_BUFFER_SIZE : buffer_size;
PRINTF_MAX_POSSIBLE_BUFFER_SIZE : (printf_size_t) buffer_size;
output_gadget_t result = discarding_gadget();
if (buffer != NULL) {
result.buffer = buffer;
Expand Down Expand Up @@ -539,9 +539,13 @@ static void print_integer(output_gadget_t* output, printf_unsigned_value_t value

#if (PRINTF_SUPPORT_DECIMAL_SPECIFIERS || PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS)

// Stores a fixed-precision representation of a double relative
// to a fixed precision (which cannot be determined by examining this structure)
struct double_components {
int_fast64_t integral;
int_fast64_t fractional;
// ... truncation of the actual fractional part of the double value, scaled
// by the precision value
bool is_negative;
};

Expand All @@ -561,10 +565,10 @@ static const double powers_of_10[NUM_DECIMAL_DIGITS_IN_INT64_T] = {
static struct double_components get_components(double number, printf_size_t precision)
{
struct double_components number_;
number_.is_negative = get_sign(number);
number_.is_negative = get_sign_bit(number);
double abs_number = (number_.is_negative) ? -number : number;
number_.integral = (int_fast64_t)abs_number;
double remainder = (abs_number - number_.integral) * powers_of_10[precision];
double remainder = (abs_number - (double) number_.integral) * powers_of_10[precision];
number_.fractional = (int_fast64_t)remainder;

remainder -= (double) number_.fractional;
Expand Down Expand Up @@ -654,7 +658,7 @@ static struct double_components get_normalized_components(bool negative, printf_
}
else {
components.fractional = (int_fast64_t) scaled_remainder;
scaled_remainder -= components.fractional;
scaled_remainder -= (double) components.fractional;

components.fractional += (scaled_remainder >= rounding_threshold);
if (scaled_remainder == rounding_threshold) {
Expand Down Expand Up @@ -765,7 +769,7 @@ static void print_decimal_number(output_gadget_t* output, double number, printf_
// internal ftoa variant for exponential floating-point type, contributed by Martijn Jasperse <m.jasperse@gmail.com>
static void print_exponential_number(output_gadget_t* output, double number, printf_size_t precision, printf_size_t width, printf_flags_t flags, char* buf, printf_size_t len)
{
const bool negative = get_sign(number);
const bool negative = get_sign_bit(number);
// This number will decrease gradually (by factors of 10) as we "extract" the exponent out of it
double abs_number = negative ? -number : number;

Expand Down

0 comments on commit 957cedd

Please sign in to comment.