Ad

This simple function tells you how many bits of precision is long double in your environment.

Introduction:

Floating-point numbers on most platforms are encoded using IEEE 754.

  • float is usually 32-bit IEEE 754 (a.k.a. single precision).
  • double is usually 64-bit IEEE 754 (a.k.a. double precision).

But what about long double?

Well, the precision of long double strongly depends on the platform and compiler. It usually is 64-bit, 80-bit, or 128-bit.

The function in this kumite, i.e. get_long_double_precision(), will return the number of bits of precision of long double.

For more info

https://en.wikipedia.org/wiki/Long_double

#include <stdlib.h> // size_t
#include <stdint.h> // uint8_t, uint16_t

uint16_t get_long_double_precision(void);
uint8_t is_big_endian(void);

uint16_t get_long_double_precision(void) {
  size_t ldsize = sizeof(long double);
  uint8_t bigendian = is_big_endian();
  
  long double test = -0.0L;
  uint8_t* test_bytes = (uint8_t*) &test;
  
  uint16_t res = 0;
  
  for (size_t i = 0; i < ldsize; i += 1) {
    size_t offset = (bigendian == 0) ? i : (ldsize - 1 - i);
    res += 8;
    if (test_bytes[offset] == 0x80) {
      break;
    }
  }
  
  return res;
}


// utility function: returns 0x01 in case the current platform is big endian,
//   otherwise returns 0x00
uint8_t is_big_endian(void) {
  uint16_t test = 0x0100;
  return ((uint8_t*) &test)[0];
}

Here's an algorithm to simplify a fraction (i.e. reduce a fraction to its lowest terms). It is written in Javascript for simplicity, but it's easily translatable to any programming language.

// e.g.:
// simplify( 15,   5) == [  3,  1]
// simplify(-50,  20) == [- 5,  2]
// simplify( 20, - 2) == [-10,  1]
// simplify(- 6, - 3) == [  2,  1]
// simplify(- 0,   3) == [  0,  1]
// simplify(  0,   0) == undefined
// simplify(  5, - 0) == undefined

function simplify(n, d){
  if (d === 0){
    return undefined;
  }

  // fraction_sign contains the sign of the fraction (1 if positive, -1 if negative)
  const fraction_sign = ((n < 0) ? -1 : 1) * ((d < 0) ? -1 : 1);
  // fraction_gcd contains the greatest common divisor of n and d
  const fraction_gcd = gcd(Math.abs(n), Math.abs(d));
  // we calculate the reduced numerator (it has the same sign as the fraction)
  const result_n = fraction_sign * Math.abs(n) / fraction_gcd;
  // we calculate the reduced denominator
  const result_d = Math.abs(d) / fraction_gcd;

  return [result_n, result_d];
}



// gcd(x, y) calculates the greatest common divisor of x and y
// x and y must be non-negative integers
// USED ALGORITHM: binary method
// BASED ON: https://en.wikipedia.org/wiki/Binary_GCD_algorithm

function gcd(x, y){
  if (x === y){
    return x;
  }

  if (x === 0){
    return y;
  }

  if (y === 0){
    return x;
  }

  if (x % 2 === 0){
    if (y % 2 === 1){
      return gcd(x >> 1, y);
    }
    else {
      return gcd(x >> 1, y >> 1) << 1;
    }
  }

  if (y % 2 === 0){
    return gcd(x, y >> 1);
  }

  if (x > y){
    return gcd((x - y) >> 1, y);
  }

  return gcd((y - x) >> 1, x);
}