【发布时间】:2019-08-30 08:04:53
【问题描述】:
我一直在网上寻找如何将 Oracle 数字转换为我可以使用的东西,但是我完全找不到任何人设法提出一个完整的算法(尤其是负指数) .
一些信息已发布在https://gotodba.com/2015/03/24/how-are-numbers-saved-in-oracle/ 上,但这是不完整的,因为它无法描述必须再次位翻转的负指数解决方案。下面是我想出的代码,使它能够成功处理(到目前为止)。我测试了从 -10,000 到 999,999 和 0.0001 到 2.0002 的值。
struct ValueExponent {
int64_t value = 0;
int32_t exponent = 0; // Powers of 10
};
int32_t CalculateExponent(const ::oracle::occi::Bytes& bytes, bool& isNegative) {
int workingExponent = static_cast<int>(bytes.byteAt(0));
isNegative = (workingExponent & 0x80) == 0;
if (isNegative)
workingExponent = ~workingExponent;
bool isNegativeExponent = (workingExponent & 0x40) == 0;
if (isNegativeExponent)
workingExponent = ~workingExponent;
return ((isNegativeExponent ? -1 : 1) * (workingExponent & 0x3f)) - (isNegativeExponent ? 1 : 0);
}
ValueExponent OracleNumberToValueExponent(const ::oracle::occi::Number& num) {
auto bytes = num.toBytes();
int64_t value = 0;
bool isNegative = false;
int32_t exponent = CalculateExponent(bytes, isNegative);
decltype(bytes.length()) max = isNegative ? bytes.length() - 1 : bytes.length();
for(decltype(bytes.length()) ix = 1; ix < max; ++ix) {
auto borig = bytes.byteAt(ix);
int b = static_cast<int>(borig);
b -= 1;
if (isNegative)
b = 100 - b;
value = value * 100 + b;
--exponent;
}
ValueExponent retval;
retval.value = isNegative ? -value : value;
retval.exponent = exponent * 2; //Oracle exponents are of 100 not 10
return retval;
}
我相信这应该能够输出任何需要的东西,但是任何对改进算法提出建议的人都会非常感激。
【问题讨论】:
-
我不懂 c++,所以无法猜测您希望代码的输出是什么样的,但 Oracle 可以将数字转换为字符串,包括科学格式,如果有帮助?例如
to_char(nbr, '0.99999EEEE') -
感谢您对 to_char 的帮助,但我希望将其转换为值指数形式以与我的其他代码兼容,这些代码适用于我的浮点数,我宁愿避免首先转换为字符串以节省一些处理能力,因为它每秒可以处理数千个。
-
您期望的输出是什么?例如。如果原始数字是 -10,000,您期望的输出是多少?
-
以 -10,000 为例,我期望任何一个:值:-1 指数:4;值:-10 指数:3;值:-100 指数:2;值:-1000 指数:1;值:-10000 指数:0;如果是 -0.1,我希望是这样的:值:-1 指数:-1
-
正在从数据库中检索您的号码?
标签: c++ oracle numbers exponent occi