Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 34 additions & 3 deletions include/FixedPointConverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -359,12 +359,20 @@ namespace ChimeraTK {
return 0;
}
else {
std::cout << "Cooked for conv to raw: " << std::dec << cookedValue
<< ", min: " << boost::fusion::at_key<UserType>(_minCookedValues)
<< ", max: " << boost::fusion::at_key<UserType>(_maxCookedValues) << std::endl;

// Do a range check first. The later overflow check in the conversion is not
// sufficient, since we can have non-standard word sizes like 12 bits.
if(cookedValue < boost::fusion::at_key<UserType>(_minCookedValues)) {
std::cout << "Neg OF . min: " << boost::fusion::at_key<UserType>(_minCookedValues) << " raw: 0x" << std::hex
<< _minRawValue << std::endl;
return _minRawValue;
}
if(cookedValue > boost::fusion::at_key<UserType>(_maxCookedValues)) {
std::cout << "Pos OF . max: " << boost::fusion::at_key<UserType>(_maxCookedValues) << " raw: 0x" << std::hex
<< _maxRawValue << std::endl;
return _maxRawValue;
}

Expand All @@ -386,7 +394,6 @@ namespace ChimeraTK {
if(_isSigned && isNegative) {
rawValue = ~rawValue;
}

// return with bit mask applied
return rawValue & _usedBitsMask;
}
Expand Down Expand Up @@ -431,14 +438,29 @@ namespace ChimeraTK {
}
}
catch(boost::numeric::negative_overflow& e) {
std::cout << "BOOST Neg OF . Cooked: " << cookedValue << " raw: 0x" << std::hex << _minRawValue << std::endl;
raw = _minRawValue;
}
catch(boost::numeric::positive_overflow& e) {
std::cout << "BOOST Pos OF . Cooked: " << cookedValue << " raw: 0x" << std::hex << _minRawValue << std::endl;
raw = _maxRawValue;
}
std::cout << "ToRawFrac . Cooked: " << cookedValue << " d_cooked: " << d_cooked << " raw: 0x" << std::hex << raw
<< std::endl;
// when cookedValue is not zero and caculated raw is not zero, but still when _usedBitsMask is applied,
// the result is the zero - fix test testInt16_fraction16 for 32bits Raw value - cases ToRaw13 and ToRaw16
// if(cookedValue && raw && !(raw & _usedBitsMask)) {
// return _minRawValue;
//}
// apply bit mask
// NOLINTNEXTLINE(hicpp-signed-bitwise)

// negative overflow not detected by boost in case when converter is signed and number of bits in converter is
// smaller than in raw type
if(cookedValue && raw && (raw & _usedBitsMask) == 0) {
return _minRawValue;
}

// apply bit mask
// NOLINTNEXTLINE(hicpp-signed-bitwise)
return raw & _usedBitsMask;
}
}
Expand Down Expand Up @@ -548,6 +570,15 @@ namespace ChimeraTK {
// fractional bit coefficients note: we loop over one of the maps only, but
// initCoefficients() will fill all maps!
boost::fusion::for_each(_minCookedValues, initCoefficients(this));

std::cout << "\n\n"
<< std::dec << "RAW BYTES: " << sizeof(RawType) << ", signed: " << _isSigned << ", nBits: " << nBits
<< ", _fractionalBits: " << _fractionalBits << std::endl;
std::cout << "_signBitMask: " << std::hex << _signBitMask << std::endl;
std::cout << "_usedBitsMask: " << std::hex << _usedBitsMask << std::endl;
std::cout << "_unusedBitsMask: " << std::hex << _unusedBitsMask << std::endl;
std::cout << "_maxRawValue: " << std::hex << _maxRawValue << std::endl;
std::cout << "_minRawValue: " << std::hex << _minRawValue << std::endl;
}

/********************************************************************************************************************/
Expand Down
132 changes: 132 additions & 0 deletions tests/executables_src/testFixedPointConverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ using namespace boost::unit_test_framework;
#define SIGNED_HEX_TO_DOUBLE(INPUT) static_cast<double>(static_cast<int32_t>(INPUT))
#define SIGNED_HEX_TO_INT64(INPUT) static_cast<int64_t>(static_cast<int32_t>(INPUT))

#define SIGNED_HEX16_TO_DOUBLE(INPUT) static_cast<double>(static_cast<int16_t>(INPUT))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about SIGNED_HEX64_TOxxx ?

#define SIGNED_HEX16_TO_INT64(INPUT) static_cast<int64_t>(static_cast<int16_t>(INPUT))

#define CHECK_SIGNED_FIXED_POINT_NO_FRACTIONAL \
checkToFixedPoint(converter, 0.25, 0); \
checkToFixedPoint(converter, -0.25, 0); \
Expand Down Expand Up @@ -851,6 +854,8 @@ BOOST_AUTO_TEST_CASE(testInt32_fraction31) {

checkToRaw(converter, (int)0x55555555, 0x7FFFFFFF);
checkToRaw(converter, (int)0xAAAAAAAA, 0x80000000);
checkToRaw(converter, (int)1, 0x7FFFFFFF);
checkToRaw(converter, (short)1, 0x7FFFFFFF);
checkToRaw(converter, (int)0, 0);
checkToRaw(converter, (int)-1, 0x80000000);
checkToRaw(converter, (unsigned int)0x55555555, 0x7FFFFFFF);
Expand Down Expand Up @@ -943,9 +948,136 @@ BOOST_AUTO_TEST_CASE(testInt32_fraction32) {
checkToRaw(converter, (short)0x5555, 0x7FFFFFFF);
checkToRaw(converter, (short)0xAAAA, 0x80000000, "ToRaw14");
checkToRaw(converter, (short)-1, 0x80000000, "ToRaw15");
checkToRaw(converter, (short)1, 0x7FFFFFFF, "ToRaw16");
// checkToRaw( converter, (unsigned short)0x5555, 0x7FFFFFFF );
}

BOOST_AUTO_TEST_CASE(testInt27_fraction27) {
FixedPointConverter<DEPRECATED_FIXEDPOINT_DEFAULT> converter("Variable27plus27signed", 27,
27); // 27 bits, 27 fractional bits, signed

checkToCooked(converter, 0xAAAAAAAA, SIGNED_HEX_TO_DOUBLE(0x02aaaaaa) * pow(2, -27));
checkToCooked(converter, 0x55555555, SIGNED_HEX_TO_DOUBLE(0xFD555555) * pow(2, -27));

checkToCooked(converter, 0xAAAAAAAA, (int)0);
checkToCooked(converter, 0x55555555, (int)0);
checkToCooked(converter, 0xAAAAAAAA, (unsigned int)0);
checkToCooked(converter, 0x55555555, (unsigned int)0);
checkToCooked(converter, 0xAAAAAAAA, (short)0);
checkToCooked(converter, 0x55555555, (short)0);
checkToCooked(converter, 0xAAAAAAAA, (unsigned short)0);
checkToCooked(converter, 0x55555555, (unsigned short)0);

checkToRaw(converter, 0.25, 0x2000000, "ToRaw1");
checkToRaw(converter, -0.25, 0x6000000, "ToRaw2");

// these values are out of range
checkToRaw(converter, 0.75, 0x3ffffff, "ToRaw3");
checkToRaw(converter, -0.75, 0x4000000, "ToRaw4");
checkToRaw(converter, 3.25, 0x3ffffff, "ToRaw5");
checkToRaw(converter, -3.25, 0x4000000, "ToRaw6");
checkToRaw(converter, 5.75, 0x3ffffff, "ToRaw7");
checkToRaw(converter, -5.75, 0x4000000, "ToRaw8");

checkToCooked(converter, 0x2000000, 0.25);
checkToCooked(converter, 0x6000000, -0.25);

checkToRaw(converter, (int)0x55555555, 0x3ffffff, "ToRaw9");
checkToRaw(converter, (int)0xAAAAAAAA, 0x4000000, "ToRaw10");
checkToRaw(converter, (int)0, 0, "ToRaw11");
checkToRaw(converter, (int)1, 0x3ffffff, "ToRaw12");
checkToRaw(converter, (int)-1, 0x4000000, "ToRaw13");
checkToRaw(converter, (short)0x5555, 0x3ffffff, "ToRaw14");
checkToRaw(converter, (short)0xAAAA, 0x4000000, "ToRaw15");
checkToRaw(converter, (short)-1, 0x4000000, "ToRaw16");
checkToRaw(converter, (short)1, 0x3ffffff, "ToRaw17");
checkToRaw(converter, (short)2, 0x3ffffff, "ToRaw18");
checkToRaw(converter, (short)-2, 0x4000000, "ToRaw19");
}

BOOST_AUTO_TEST_CASE(testInt16_fraction16) {
FixedPointConverter<DEPRECATED_FIXEDPOINT_DEFAULT> converter("Variable16plus16signed", 16,
16); // 16 bits, 16 fractional bits, signed

checkToCooked(converter, 0xAAAA, SIGNED_HEX16_TO_DOUBLE(0xAAAA) * pow(2, -16), "ToCoocked1");
checkToCooked(converter, 0x5555, SIGNED_HEX16_TO_DOUBLE(0x5555) * pow(2, -16), "ToCoocked2");
checkToCooked(converter, 0xAAAA, (int)0);
checkToCooked(converter, 0x5555, (int)0);
checkToCooked(converter, 0xAAAA, (unsigned int)0);
checkToCooked(converter, 0x5555, (unsigned int)0);
checkToCooked(converter, 0xAAAA, (short)0);
checkToCooked(converter, 0x5555, (short)0);
checkToCooked(converter, 0xAAAA, (unsigned short)0);
checkToCooked(converter, 0x5555, (unsigned short)0);

checkToRaw(converter, 0.25, 0x4000, "ToRaw1");
checkToRaw(converter, -0.25, 0xC000, "ToRaw2");

// these values are out of range
checkToRaw(converter, 0.75, 0x7FFF, "ToRaw3");
checkToRaw(converter, -0.75, 0x8000, "ToRaw4");
checkToRaw(converter, 3.25, 0x7FFF, "ToRaw5");
checkToRaw(converter, -3.25, 0x8000, "ToRaw6");
checkToRaw(converter, 5.75, 0x7FFF, "ToRaw7");
checkToRaw(converter, -5.75, 0x8000, "ToRaw8");

checkToCooked(converter, 0x4000, 0.25);
checkToCooked(converter, 0xC000, -0.25);

checkToRaw(converter, (int)0x55555555, 0x7FFF, "ToRaw9");
checkToRaw(converter, (int)0xAAAAAAAA, 0x8000, "ToRaw10");
checkToRaw(converter, (int)0, 0, "ToRaw11");
checkToRaw(converter, (int)1, 0x7FFF, "ToRaw12");
checkToRaw(converter, (int)-1, 0x8000, "ToRaw13");

checkToRaw(converter, (short)0x5555, 0x7FFF, "ToRaw14");
checkToRaw(converter, (short)0xAAAA, 0x8000, "ToRaw15");
checkToRaw(converter, (short)-1, 0x8000, "ToRaw16");
checkToRaw(converter, (short)-2, 0x8000, "ToRaw17");
}

BOOST_AUTO_TEST_CASE(testInt14_fraction14) {
FixedPointConverter<DEPRECATED_FIXEDPOINT_DEFAULT> converter("Variable14plus14signed", 14,
14); // 16 bits, 1 6 fractional bits, signed

checkToCooked(converter, 0xAAAA, SIGNED_HEX_TO_DOUBLE(0xFFFFEAAA) * pow(2, -14));
checkToCooked(converter, 0x5555, SIGNED_HEX_TO_DOUBLE(0x1555) * pow(2, -14));

checkToCooked(converter, 0xAAAA, (int)0);
checkToCooked(converter, 0x5555, (int)0);
checkToCooked(converter, 0xAAAA, (unsigned int)0);
checkToCooked(converter, 0x5555, (unsigned int)0);
checkToCooked(converter, 0xAAAA, (short)0);
checkToCooked(converter, 0x5555, (short)0);
checkToCooked(converter, 0xAAAA, (unsigned short)0);
checkToCooked(converter, 0x5555, (unsigned short)0);

checkToRaw(converter, 0.25, 0x1000, "ToRaw1");
checkToRaw(converter, -0.25, 0x3000, "ToRaw2");

// these values are out of range
checkToRaw(converter, 0.75, 0x1FFF, "ToRaw3");
checkToRaw(converter, -0.75, 0x2000, "ToRaw4");
checkToRaw(converter, 3.25, 0x1FFF, "ToRaw5");
checkToRaw(converter, -3.25, 0x2000, "ToRaw6");
checkToRaw(converter, 5.75, 0x1FFF, "ToRaw7");
checkToRaw(converter, -5.75, 0x2000, "ToRaw8");

checkToCooked(converter, 0x1000, 0.25);
checkToCooked(converter, 0x3000, -0.25);

checkToRaw(converter, (int)0x55555555, 0x1FFF, "ToRaw9");
checkToRaw(converter, (int)0xAAAAAAAA, 0x2000, "ToRaw10");
checkToRaw(converter, (int)0, 0, "ToRaw11");
checkToRaw(converter, (int)1, 0x1FFF, "ToRaw12");
checkToRaw(converter, (int)-1, 0x2000, "ToRaw13");

checkToRaw(converter, (short)0x5555, 0x1FFF, "ToRaw14");
checkToRaw(converter, (short)0xAAAA, 0x2000, "ToRaw15");
checkToRaw(converter, (short)-1, 0x2000, "ToRaw16");
checkToRaw(converter, (short)-2, 0x2000, "ToRaw17");
}

BOOST_AUTO_TEST_CASE(testUInt32_fraction32) {
FixedPointConverter<DEPRECATED_FIXEDPOINT_DEFAULT> converter("Variable32plus32unsigned", 32, 32,
false); // 32 bits, 32 fractional bits, not signed
Expand Down
Loading