Revision 30849ea7
Added by David Sorber about 4 years ago
| software/fixed/CMakeLists.txt | ||
|---|---|---|
|
|
||
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O3 -march=native -fuse-ld=gold -flto")
|
||
|
|
||
|
ADD_EXECUTABLE(fixed_util ${CMAKE_CURRENT_SOURCE_DIR}/fixed_util.cc)
|
||
|
ADD_EXECUTABLE(parse_test ${CMAKE_CURRENT_SOURCE_DIR}/parse_test.cc)
|
||
|
SET(sources
|
||
|
${CMAKE_CURRENT_SOURCE_DIR}/int128.cc
|
||
|
)
|
||
|
|
||
|
ADD_EXECUTABLE(fixed_util ${sources} ${CMAKE_CURRENT_SOURCE_DIR}/fixed_util.cc)
|
||
|
ADD_EXECUTABLE(parse_test ${sources} ${CMAKE_CURRENT_SOURCE_DIR}/parse_test.cc)
|
||
|
|
||
|
# Test executables
|
||
|
ADD_EXECUTABLE(fixed_test ${CMAKE_CURRENT_SOURCE_DIR}/fixed_test.cc)
|
||
|
ADD_EXECUTABLE(fixed_test ${sources} ${CMAKE_CURRENT_SOURCE_DIR}/fixed_test.cc)
|
||
|
TARGET_LINK_LIBRARIES(fixed_test ${EXTERNAL_LIBS})
|
||
|
|
||
|
ADD_EXECUTABLE(int128_test ${CMAKE_CURRENT_SOURCE_DIR}/int128_test.cc)
|
||
|
ADD_EXECUTABLE(int128_test ${sources} ${CMAKE_CURRENT_SOURCE_DIR}/int128_test.cc)
|
||
|
TARGET_LINK_LIBRARIES(int128_test ${EXTERNAL_LIBS})
|
||
|
|
||
|
ADD_TEST(NAME test_int128t COMMAND int128_test)
|
||
| software/fixed/fixed.h | ||
|---|---|---|
|
#endif
|
||
|
|
||
|
#if SUPPORT_128_INTS
|
||
|
#include "Utilities/int128.h"
|
||
|
#include "int128.h"
|
||
|
//~ #include "Utilities/int128.h"
|
||
|
#endif
|
||
|
|
||
|
|
||
| ... | ... | |
|
friend constexpr inline bool operator>=(
|
||
|
const fixed<I, F, STI, STF>& x, const fixed<I, F, STI, STF>& y) noexcept;
|
||
|
|
||
|
// Divide by unsigned int
|
||
|
// Multiply by integer
|
||
|
template<typename I, typename F, typename STI, typename STF>
|
||
|
friend constexpr inline fixed<I, F, STI, STF> operator*(
|
||
|
const fixed<I, F, STI, STF>& x, const int64_t& y);
|
||
|
|
||
|
// Divide by integer
|
||
|
template<typename I, typename F, typename STI, typename STF>
|
||
|
friend constexpr inline fixed<I, F, STI, STF> operator/(
|
||
|
const fixed<I, F, STI, STF>& x, const int64_t& y);
|
||
| ... | ... | |
|
constexpr inline fixed<I, F, STI, STF> operator/(
|
||
|
const fixed<I, F, STI, STF>& x, const fixed<I, F, STI, STF>& y) noexcept = delete;
|
||
|
|
||
|
// Division by unsigned int
|
||
|
// Multiplication by integer
|
||
|
template<typename I, typename F, typename STI, typename STF>
|
||
|
constexpr inline fixed<I, F, STI, STF> operator*(
|
||
|
const fixed<I, F, STI, STF>& x, const int64_t& y)
|
||
|
{
|
||
|
fixed<I, F, STI, STF> newVal;
|
||
|
//~ bool negativeDivisorFlag = (y < 0);
|
||
|
//~ bool negativeDividendFlag = (x.m_integer < 0) ||
|
||
|
//~ (x.m_integer == fixed<I, F, STI, STF>::NEGATIVE_ZERO);
|
||
|
//~ bool negativeZeroFlag = false;
|
||
|
//~ I integerX = x.m_integer;
|
||
|
//~ if (__unlikely((integerX == fixed<I, F, STI, STF>::NEGATIVE_ZERO)))
|
||
|
//~ {
|
||
|
//~ integerX = 0;
|
||
|
//~ negativeZeroFlag = true;
|
||
|
//~ }
|
||
|
|
||
|
// Straight multiply for integer portion
|
||
|
newVal.m_integer = x.m_integer * y;
|
||
|
|
||
|
std::cout << "INTEGER: " << newVal.m_integer << std::endl;
|
||
|
|
||
|
std::cout << "Frac digits: " << fixed<I, F, STI, STF>::fractional_decimal_digits << std::endl;
|
||
|
std::cout << "Half Frac digits: " << (fixed<I, F, STI, STF>::fractional_decimal_digits / 2) << std::endl;
|
||
|
|
||
|
uint32_t index = (fixed<I, F, STI, STF>::fractional_decimal_digits / 2);
|
||
|
|
||
|
#if SUPPORT_128_INTS
|
||
|
uint128_t scaler = fixed<I, F, STI, STF>::SCALE_VALUES[index];
|
||
|
#else
|
||
|
uint64_t scaler = fixed<I, F, STI, STF>::SCALE_VALUES[index];
|
||
|
#endif
|
||
|
|
||
|
// Handle upper and lower portions of fractional value separarely so that
|
||
|
// the integer carry can be handled
|
||
|
std::cout << "[1] FRAC upper: " << (x.m_fractional / scaler) << std::endl;
|
||
|
F fracUpper = (x.m_fractional / scaler) * y;
|
||
|
std::cout << "[2] FRAC upper: " << fracUpper << std::endl;
|
||
|
newVal.m_fractional = (fracUpper % (scaler * 10)) * scaler;
|
||
|
std::cout << "NEW FRAC upper: " << newVal.m_fractional << std::endl;
|
||
|
|
||
|
F carry = (fracUpper / (scaler * 10));
|
||
|
std::cout << "Carry: " << carry << std::endl;
|
||
|
newVal.m_integer += carry;
|
||
|
|
||
|
F fracLower = (x.m_fractional % scaler) * y;
|
||
|
std::cout << "FRAC lower: " << fracLower << std::endl;
|
||
|
newVal.m_fractional += fracLower;
|
||
|
|
||
|
return newVal;
|
||
|
}
|
||
|
|
||
|
// Division by integer
|
||
|
template<typename I, typename F, typename STI, typename STF>
|
||
|
constexpr inline fixed<I, F, STI, STF> operator/(
|
||
|
const fixed<I, F, STI, STF>& x, const int64_t& y)
|
||
| software/fixed/fixed_util.cc | ||
|---|---|---|
|
int main(int argc, char** argv)
|
||
|
{
|
||
|
std::cout << "Fixed Type Test Util\n" << std::endl;
|
||
|
|
||
|
fixed_64_64 val;
|
||
|
fixed_64_64 val2;
|
||
|
val.parse("0.314159263538979");
|
||
|
std::cout << "[1] Val: " << val << std::endl;
|
||
|
val2 = val * 10;
|
||
|
std::cout << "[2] Val: " << val2 << std::endl;
|
||
|
|
||
|
val2 = val * 86;
|
||
|
std::cout << "[3] Val: " << val2 << std::endl;
|
||
|
|
||
|
#if 0
|
||
|
//-------------------------------------------------------------------------
|
||
|
fixed_64_64 foobar;
|
||
|
std::cout << "Type size: " << sizeof(fixed_64_64) << std::endl;
|
||
| ... | ... | |
|
uint128_t u128Val = strtoull_128(strVal, nullptr, 0);
|
||
|
std::cout << "String value: " << strVal << std::endl;
|
||
|
std::cout << "Parsed value: " << u128Val << std::endl;
|
||
|
#endif
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
Initial version of integer division for the fixed point type.