Closed emiliopaolini closed 3 years ago
It is very difficult to show you an example since i am using scaled_integer as the computation type for a deep learning library. I just noticed that by changing the computation type from using X = cnl::scaled_integer<cnl::overflow_integer<short int,cnl::saturated_overflow_tag>, cnl::power<-8>>; to using X = cnl::scaled_integer<cnl::overflow_integer<cnl::signed_multiprecision<16>,cnl::saturated_overflow_tag>, cnl::power<-8>>; the results change. Anyway if i use this type:
using X = cnl::static_number<16, -8, cnl::native_rounding_tag,cnl::saturated_overflow_tag>;
i obtain the same results of
X = cnl::scaled_integer<cnl::overflow_integer<short int,cnl::saturated_overflow_tag>, cnl::power<-8>>;
. Maybe this can help in finding the problem with signed_multiprecision?
Maybe this can help in finding the problem with signed_multiprecision?
All of this sounds consistent with your values overflowing as described in the FAQ.
You could try the following:
cnl::signed_multiprecision<32>
instead. Does the problem go away? Then it's probably integer overflow.saturated_overflow_tag
with trapping_overflow_tag
, does the program halt? If so, again, this is because you are suffering overflow.cnl::static_number
fix the problem? That number type -- as well as short int
-- has properties which help if avoid overflowing on values wider than 16 bits.Essentially, when you multiply two 16-bit numbers together, you get a 32-bit number. If you store this result in a 16-bit type, e.g. cnl::signed_multiprecision<16>
, then that 16-bit number will overflow when the result of the 16-bit multiplication is too wide. E.g. 10,000 * 10,000 is 100,000,000 which is too wide for a 16-bit integer.
Even if you assign the result back to a 16-bit number with exponent=-8, the overflow will already have occurred.
Ok maybe i understand the problem. Probably there was an overflow that i didn't notice. The thing that i don't get is the following: why these two types, that both saturate when overflow happens, give different results?
using X = cnl::scaled_integer<cnl::overflow_integer<cnl::signed_multiprecision<16>,cnl::saturated_overflow_tag>, cnl::power<-8>>; using X = cnl::scaled_integer<cnl::overflow_integer<short int,cnl::saturated_overflow_tag>, cnl::power<-8>>;
Many operations on fundamental integer types promote to wider types. On common systems, short int operations promote to int, thus avoiding the overflow in the first place:
short s = 10'000;
auto ss = s*s; // type=int; value=100'000'000
Ok i understand! Thank you very much!
Hi everyone, i am trying to define a fixed_point type on 16 bits. I would like to use Boost::multiprecision as base type. I know it is possible to do the same by using types defined only in CNL, for example:
using X = cnl::scaled_integer<cnl::overflow_integer<short int,cnl::saturated_overflow_tag>, cnl::power<-8>>;
Instead of the short int, i would like to use boost::multiprecision or cnl::signed_multiprecision. Now the problem is the following: if i use this type:using X = cnl::scaled_integer<cnl::overflow_integer<cnl::signed_multiprecision<16>,cnl::saturated_overflow_tag>, cnl::power<-8>>;
the same program, loses accuracy and gives strange results. Do you have any suggestions on how to define a fixed_point type on a custom number of bits that can saturate? Possibly by using boost::multiprecision. Thanks in advance!