c3c icon indicating copy to clipboard operation
c3c copied to clipboard

min/max values of types

Open data-man opened this issue 3 years ago • 6 comments

import std::io;

macro print_type_info(...)
{
    $for (var $i = 0; $i < $vacount; $i++):
        io::printfln("type: %s", $nameof($vatype($i)));
        io::printfln("%s.sizeof = %d", $nameof($vatype($i)), $vatype($i).sizeof);
        io::printfln("%s.min = %d", $nameof($vatype($i)), $vatype($i).min);
        io::printfln("%s.max = %d\n", $nameof($vatype($i)), $vatype($i).max);
    $endfor;
}

fn void main()
{
    io::printfln("Unsigned integers:");
    print_type_info(char, ushort, uint, ulong, uptr, uptrdiff, usize, uint128);
    io::printfln("Signed integers:");
    print_type_info(ichar, short, int, long, iptr, iptrdiff, isize, int128);
    io::printfln("Floats:");
    print_type_info(float, double, float128);

//    print_type_info(float16); FATAL ERROR Should be unreachable -> in type_from_token @ in c3c/src/compiler/types.c:1452
//    print_type_info(bool); //Error: 'bool' does not have a property 'max'. Why?
}

My results:

Unsigned integers:
type: char
char.sizeof = 1
char.min = 0
char.max = 255

type: ushort
ushort.sizeof = 2
ushort.min = 0
ushort.max = 65535

type: uint
uint.sizeof = 4
uint.min = 0
uint.max = 4294967295

type: ulong
ulong.sizeof = 8
ulong.min = 0
ulong.max = 18446744073709551615

type: uptr
uptr.sizeof = 8
uptr.min = 0
uptr.max = 18446744073709551615

type: uptrdiff
uptrdiff.sizeof = 8
uptrdiff.min = 0
uptrdiff.max = 18446744073709551615

type: usize
usize.sizeof = 8
usize.min = 0
usize.max = 18446744073709551615

type: uint128
uint128.sizeof = 16
uint128.min = 0
uint128.max = 340282366920938463463374607431768211455

Signed integers:
type: ichar
ichar.sizeof = 1
ichar.min = -1
ichar.max = 127

type: short
short.sizeof = 2
short.min = -1
short.max = 32767

type: int
int.sizeof = 4
int.min = -1
int.max = 2147483647

type: long
long.sizeof = 8
long.min = -1
long.max = 9223372036854775807

type: iptr
iptr.sizeof = 8
iptr.min = -1
iptr.max = 9223372036854775807

type: iptrdiff
iptrdiff.sizeof = 8
iptrdiff.min = -1
iptrdiff.max = 9223372036854775807

type: isize
isize.sizeof = 8
isize.min = -1
isize.max = 9223372036854775807

type: int128
int128.sizeof = 16
int128.min = -1
int128.max = 170141183460469231731687303715884105727

Floats:
type: float
float.sizeof = 4
float.min = 0
float.max = 340282346638528859811704183484516925440

type: double
double.sizeof = 8
double.min = 0
double.max = 0

type: float128
float128.sizeof = 16
float128.min = 0
float128.max = 0

data-man avatar Sep 13 '22 08:09 data-man

Float min is correct, since it is FLT_MIN which is the smallest possible float and you're using %d which rounds it to an integer. Use %s instead.

lerno avatar Sep 14 '22 09:09 lerno

Float min is correct, since it is FLT_MIN which is the smallest possible float

I think it is incorrect and the value should be equal to real minimum.

you're using %d

OMG, sorry! :)

data-man avatar Sep 14 '22 10:09 data-man

I've made a commit #571 which addresses the int issues. It's still a bit unclear to me how I want to support float16, float128 and int128 on platforms that don't have the support.

For the floats I'm two minds about that. There are actually multiple values that are of interest for floats:

  1. FLT_EPSILON
  2. FLT_DIG
  3. FLT_MANT_DIG
  4. FLT_MAX_10_EXP
  5. FLT_MIN
  6. FLT_MAX_EXPR
  7. FLT_MIN_EXP

These could either be constants or accessed using dot syntax.

lerno avatar Sep 14 '22 10:09 lerno

These could either be constants or accessed using dot syntax.

Or min/max can be removed from built-in features and implemented in stdlib (like C++ numeric_limits).

data-man avatar Sep 14 '22 10:09 data-man

From cppreference.com/Numeric limits:

#include <stdio.h>
#include <float.h>
#include <math.h>

int main(void)
{
    printf("DECIMAL_DIG     = %d\n", DECIMAL_DIG);
    printf("FLT_DECIMAL_DIG = %d\n", FLT_DECIMAL_DIG);
    printf("FLT_RADIX       = %d\n", FLT_RADIX);
    printf("FLT_MIN         = %e\n", FLT_MIN);
    printf("FLT_TRUE_MIN    = %e\n", FLT_TRUE_MIN);
    printf("FLT_MAX         = %e\n", FLT_MAX);
    printf("FLT_EPSILON     = %e\n", FLT_EPSILON);
    printf("FLT_DIG         = %d\n", FLT_DIG);
    printf("FLT_MANT_DIG    = %d\n", FLT_MANT_DIG);
    printf("FLT_MIN_EXP     = %d\n", FLT_MIN_EXP);
    printf("FLT_MIN_10_EXP  = %d\n", FLT_MIN_10_EXP);
    printf("FLT_MAX_EXP     = %d\n", FLT_MAX_EXP);
    printf("FLT_MAX_10_EXP  = %d\n", FLT_MAX_10_EXP);
    printf("FLT_ROUNDS      = %d\n", FLT_ROUNDS);
    printf("FLT_EVAL_METHOD = %d\n", FLT_EVAL_METHOD);
    printf("FLT_HAS_SUBNORM = %d\n", FLT_HAS_SUBNORM);

    printf("DBL_DECIMAL_DIG = %d\n", DBL_DECIMAL_DIG);
    printf("DBL_MIN         = %e\n", DBL_MIN);
    printf("DBL_TRUE_MIN    = %e\n", DBL_TRUE_MIN);
    printf("DBL_MAX         = %e\n", DBL_MAX);
    printf("DBL_EPSILON     = %e\n", DBL_EPSILON);
    printf("DBL_DIG         = %d\n", DBL_DIG);
    printf("DBL_MANT_DIG    = %d\n", DBL_MANT_DIG);
    printf("DBL_MIN_EXP     = %d\n", DBL_MIN_EXP);
    printf("DBL_MIN_10_EXP  = %d\n", DBL_MIN_10_EXP);
    printf("DBL_MAX_EXP     = %d\n", DBL_MAX_EXP);
    printf("DBL_MAX_10_EXP  = %d\n", DBL_MAX_10_EXP);
    printf("DBL_HAS_SUBNORM = %d\n", DBL_HAS_SUBNORM);

    printf("LDBL_DECIMAL_DIG = %d\n", LDBL_DECIMAL_DIG);
    printf("LDBL_MIN         = %Le\n", LDBL_MIN);
    printf("LDBL_TRUE_MIN    = %Le\n", LDBL_TRUE_MIN);
    printf("LDBL_MAX         = %Le\n", LDBL_MAX);
    printf("LDBL_EPSILON     = %Le\n", LDBL_EPSILON);
    printf("LDBL_DIG         = %d\n", LDBL_DIG);
    printf("LDBL_MANT_DIG    = %d\n", LDBL_MANT_DIG);
    printf("LDBL_MIN_EXP     = %d\n", LDBL_MIN_EXP);
    printf("LDBL_MIN_10_EXP  = %d\n", LDBL_MIN_10_EXP);
    printf("LDBL_MAX_EXP     = %d\n", LDBL_MAX_EXP);
    printf("LDBL_MAX_10_EXP  = %d\n", LDBL_MAX_10_EXP);
    printf("LDBL_HAS_SUBNORM = %d\n", LDBL_HAS_SUBNORM);
}
DECIMAL_DIG     = 21
FLT_DECIMAL_DIG = 9
FLT_RADIX       = 2
FLT_MIN         = 1.175494e-38
FLT_TRUE_MIN    = 1.401298e-45
FLT_MAX         = 3.402823e+38
FLT_EPSILON     = 1.192093e-07
FLT_DIG         = 6
FLT_MANT_DIG    = 24
FLT_MIN_EXP     = -125
FLT_MIN_10_EXP  = -37
FLT_MAX_EXP     = 128
FLT_MAX_10_EXP  = 38
FLT_ROUNDS      = 1
FLT_EVAL_METHOD = 0
FLT_HAS_SUBNORM = 1
DBL_DECIMAL_DIG = 17
DBL_MIN         = 2.225074e-308
DBL_TRUE_MIN    = 4.940656e-324
DBL_MAX         = 1.797693e+308
DBL_EPSILON     = 2.220446e-16
DBL_DIG         = 15
DBL_MANT_DIG    = 53
DBL_MIN_EXP     = -1021
DBL_MIN_10_EXP  = -307
DBL_MAX_EXP     = 1024
DBL_MAX_10_EXP  = 308
DBL_HAS_SUBNORM = 1
LDBL_DECIMAL_DIG = 21
LDBL_MIN         = 3.362103e-4932
LDBL_TRUE_MIN    = 3.645200e-4951
LDBL_MAX         = 1.189731e+4932
LDBL_EPSILON     = 1.084202e-19
LDBL_DIG         = 18
LDBL_MANT_DIG    = 64
LDBL_MIN_EXP     = -16381
LDBL_MIN_10_EXP  = -4931
LDBL_MAX_EXP     = 16384
LDBL_MAX_10_EXP  = 4932
LDBL_HAS_SUBNORM = 1

FLT_MIN == 1.175494e-38 FLT_TRUE_MIN = 1.401298e-45 DBL_MIN == 2.225074e-308 DBL_TRUE_MIN = 4.940656e-324 LDBL_MIN == 3.362103e-4932 LDBL_TRUE_MIN = 3.645200e-4951

data-man avatar Sep 14 '22 14:09 data-man

Those limits are in math.c3 already.

lerno avatar Sep 16 '22 06:09 lerno

float.min now returns -float.max

lerno avatar Oct 20 '22 19:10 lerno

float128.min = 0.000000
float128.max = 0.000000

data-man avatar Oct 22 '22 14:10 data-man

Yes, no support for float128 yet.

lerno avatar Oct 22 '22 14:10 lerno

I have opened the issue for float128 as #773. I'll close this one since all the others should be done.

lerno avatar Jun 02 '23 09:06 lerno