Autonomy Software C++ 24.5.1
Welcome to the Autonomy Software repository of the Mars Rover Design Team (MRDT) at Missouri University of Science and Technology (Missouri S&T)! API reference contains the source code and other resources for the development of the autonomy software for our Mars rover. The Autonomy Software project aims to compete in the University Rover Challenge (URC) by demonstrating advanced autonomous capabilities and robust navigation algorithms.
Loading...
Searching...
No Matches
duckdb::DecimalCastOperation Struct Reference

Static Public Member Functions

template<class T , bool NEGATIVE>
static bool HandleDigit (T &state, uint8_t digit)
 
template<class T , bool NEGATIVE>
static bool HandleHexDigit (T &state, uint8_t digit)
 
template<class T , bool NEGATIVE>
static bool HandleBinaryDigit (T &state, uint8_t digit)
 
template<class T , bool NEGATIVE>
static void RoundUpResult (T &state)
 
template<class T , bool NEGATIVE>
static bool HandleExponent (T &state, int32_t exponent)
 
template<class T , bool NEGATIVE, bool ALLOW_EXPONENT>
static bool HandleDecimal (T &state, uint8_t digit)
 
template<class T , bool NEGATIVE>
static bool TruncateExcessiveDecimals (T &state)
 
template<class T , bool NEGATIVE>
static bool Finalize (T &state)
 

Member Function Documentation

◆ HandleDigit()

template<class T , bool NEGATIVE>
static bool duckdb::DecimalCastOperation::HandleDigit ( T &  state,
uint8_t  digit 
)
inlinestatic
55101 {
55102 if (state.result == 0 && digit == 0) {
55103 // leading zero's don't count towards the digit count
55104 return true;
55105 }
55106 if (state.digit_count == state.width - state.scale) {
55107 // width of decimal type is exceeded!
55108 return false;
55109 }
55110 state.digit_count++;
55111 if (NEGATIVE) {
55112 if (state.result < (NumericLimits<typename T::StoreType>::Minimum() / 10)) {
55113 return false;
55114 }
55115 state.result = state.result * 10 - digit;
55116 } else {
55117 if (state.result > (NumericLimits<typename T::StoreType>::Maximum() / 10)) {
55118 return false;
55119 }
55120 state.result = state.result * 10 + digit;
55121 }
55122 return true;
55123 }

◆ HandleHexDigit()

template<class T , bool NEGATIVE>
static bool duckdb::DecimalCastOperation::HandleHexDigit ( T &  state,
uint8_t  digit 
)
inlinestatic
55126 {
55127 return false;
55128 }

◆ HandleBinaryDigit()

template<class T , bool NEGATIVE>
static bool duckdb::DecimalCastOperation::HandleBinaryDigit ( T &  state,
uint8_t  digit 
)
inlinestatic
55131 {
55132 return false;
55133 }

◆ RoundUpResult()

template<class T , bool NEGATIVE>
static void duckdb::DecimalCastOperation::RoundUpResult ( T &  state)
inlinestatic
55136 {
55137 if (NEGATIVE) {
55138 state.result -= 1;
55139 } else {
55140 state.result += 1;
55141 }
55142 }

◆ HandleExponent()

template<class T , bool NEGATIVE>
static bool duckdb::DecimalCastOperation::HandleExponent ( T &  state,
int32_t  exponent 
)
inlinestatic
55145 {
55146 auto decimal_excess = (state.decimal_count > state.scale) ? state.decimal_count - state.scale : 0;
55147 if (exponent > 0) {
55148 state.exponent_type = ExponentType::POSITIVE;
55149 // Positive exponents need up to 'exponent' amount of digits
55150 // Everything beyond that amount needs to be truncated
55151 if (decimal_excess > exponent) {
55152 // We've allowed too many decimals
55153 state.excessive_decimals = UnsafeNumericCast<uint8_t>(decimal_excess - exponent);
55154 exponent = 0;
55155 } else {
55156 exponent -= decimal_excess;
55157 }
55158 D_ASSERT(exponent >= 0);
55159 } else if (exponent < 0) {
55160 state.exponent_type = ExponentType::NEGATIVE;
55161 }
55162 if (!Finalize<T, NEGATIVE>(state)) {
55163 return false;
55164 }
55165 if (exponent < 0) {
55166 bool round_up = false;
55167 for (idx_t i = 0; i < idx_t(-int64_t(exponent)); i++) {
55168 auto mod = state.result % 10;
55169 round_up = NEGATIVE ? mod <= -5 : mod >= 5;
55170 state.result /= 10;
55171 if (state.result == 0) {
55172 break;
55173 }
55174 }
55175 if (round_up) {
55176 RoundUpResult<T, NEGATIVE>(state);
55177 }
55178 return true;
55179 } else {
55180 // positive exponent: append 0's
55181 for (idx_t i = 0; i < idx_t(exponent); i++) {
55182 if (!HandleDigit<T, NEGATIVE>(state, 0)) {
55183 return false;
55184 }
55185 }
55186 return true;
55187 }
55188 }
::int64_t int64_t
uint64_t idx_t
a saner size_t for loop indices etc
Definition duckdb.hpp:237

◆ HandleDecimal()

template<class T , bool NEGATIVE, bool ALLOW_EXPONENT>
static bool duckdb::DecimalCastOperation::HandleDecimal ( T &  state,
uint8_t  digit 
)
inlinestatic

If we expect an exponent, we need to preserve the decimals But we don't want to overflow, so we prevent overflowing the result with this check

55191 {
55192 if (state.decimal_count == state.scale && !state.round_set) {
55193 // Determine whether the last registered decimal should be rounded or not
55194 state.round_set = true;
55195 state.should_round = digit >= 5;
55196 }
55197 if (!ALLOW_EXPONENT && state.decimal_count == state.scale) {
55198 // we exceeded the amount of supported decimals
55199 // however, we don't throw an error here
55200 // we just truncate the decimal
55201 return true;
55202 }
55205 if (state.digit_count + state.decimal_count >= DecimalWidth<decltype(state.result)>::max) {
55206 return true;
55207 }
55208 state.decimal_count++;
55209 if (NEGATIVE) {
55210 state.result = state.result * 10 - digit;
55211 } else {
55212 state.result = state.result * 10 + digit;
55213 }
55214 return true;
55215 }
static softfloat max()
Here is the call graph for this function:

◆ TruncateExcessiveDecimals()

template<class T , bool NEGATIVE>
static bool duckdb::DecimalCastOperation::TruncateExcessiveDecimals ( T &  state)
inlinestatic

Only round up when exponents are involved

55218 {
55219 D_ASSERT(state.excessive_decimals);
55220 bool round_up = false;
55221 for (idx_t i = 0; i < state.excessive_decimals; i++) {
55222 auto mod = state.result % 10;
55223 round_up = NEGATIVE ? mod <= -5 : mod >= 5;
55224 state.result /= static_cast<typename T::StoreType>(10.0);
55225 }
55227 if (state.exponent_type == ExponentType::POSITIVE && round_up) {
55228 RoundUpResult<T, NEGATIVE>(state);
55229 }
55230 D_ASSERT(state.decimal_count > state.scale);
55231 state.decimal_count = state.scale;
55232 return true;
55233 }

◆ Finalize()

template<class T , bool NEGATIVE>
static bool duckdb::DecimalCastOperation::Finalize ( T &  state)
inlinestatic

Did not encounter an exponent, but ALLOW_EXPONENT was on

55236 {
55237 if (state.exponent_type != ExponentType::POSITIVE && state.decimal_count > state.scale) {
55239 state.excessive_decimals = state.decimal_count - state.scale;
55240 }
55241 if (state.excessive_decimals && !TruncateExcessiveDecimals<T, NEGATIVE>(state)) {
55242 return false;
55243 }
55244 if (state.exponent_type == ExponentType::NONE && state.round_set && state.should_round) {
55245 RoundUpResult<T, NEGATIVE>(state);
55246 }
55247 // if we have not gotten exactly "scale" decimals, we need to multiply the result
55248 // e.g. if we have a string "1.0" that is cast to a DECIMAL(9,3), the value needs to be 1000
55249 // but we have only gotten the value "10" so far, so we multiply by 1000
55250 for (uint8_t i = state.decimal_count; i < state.scale; i++) {
55251 state.result *= 10;
55252 }
55253 if (NEGATIVE) {
55254 return state.result > -state.limit;
55255 } else {
55256 return state.result < state.limit;
55257 }
55258 }
::uint8_t uint8_t

The documentation for this struct was generated from the following file: