Project

General

Profile

« Previous | Next » 

Revision 30849ea7

Added by David Sorber about 4 years ago

Initial version of integer division for the fixed point type.

View differences:

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;
}

Also available in: Unified diff