MCPcopy Create free account
hub / github.com/FirebirdSQL/firebird / makeBcdKey

Method makeBcdKey

src/common/DecFloat.cpp:1066–1136  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1064}
1065
1066ULONG Decimal128::makeBcdKey(vary* buf, unsigned char *coeff, int sign, int exp, const int bias, const unsigned pMax)
1067{
1068 // normalize coeff & exponent
1069 unsigned dig = digits(pMax, coeff, exp);
1070
1071 // exponent bias and sign
1072 exp += (bias + 1);
1073 if (!dig)
1074 exp = 0;
1075 if (sign)
1076 exp = -exp;
1077 exp += 2 * (bias + 1); // make it positive
1078 fb_assert(exp >= 0 && exp < 64 * 1024);
1079
1080 // encode exp
1081 char* k = buf->vary_string;
1082 *k++ = exp >> 8;
1083 *k++ = exp & 0xff;
1084
1085 // invert negative
1086 unsigned char* const end = &coeff[dig];
1087 if (sign && dig)
1088 {
1089 fb_assert(end[-1]);
1090 --end[-1];
1091
1092 for (unsigned char* p = coeff; p < end; ++p)
1093 *p = 9 - *p;
1094 }
1095
1096 // Some 0's in the end - caller, do not forget to reserve additional space on stack
1097 end[0] = end[1] = 0;
1098
1099 // Avoid bad data in k in case when coeff is zero
1100 *k = 0;
1101
1102 // Shifts for moving 10-bit values to bytes buffer
1103 struct ShiftTable { UCHAR rshift, lshift; };
1104 static ShiftTable table[4] =
1105 {
1106 { 2, 6 },
1107 { 4, 4 },
1108 { 6, 2 },
1109 { 8, 0 }
1110 };
1111
1112 // compress coeff - 3 decimal digits (999) per 10 bits (1023)
1113 unsigned char* p = coeff;
1114 for (ShiftTable* t = table; p < end; p += 3)
1115 {
1116 USHORT val = p[0] * 100 + p[1] * 10 + p[2];
1117 fb_assert(val < 1000); // 1024, 10 bit
1118 *k |= (val >> t->rshift);
1119 ++k;
1120 *k = (val << t->lshift);
1121 if (!t->lshift)
1122 {
1123 ++k;

Callers

nothing calls this directly

Calls 1

digitsFunction · 0.70

Tested by

no test coverage detected