我想编写一个函数,它找到值与最近的两个浮点值之间的最小小数,这两个浮点值分别越来越大。
例如十进制数0.1有
decimal representation: 0.1
binary representation: 0 01111011 10011001100110011001101
actual value of binary representation: 0.10000000149011612
可以通过将二进制表示的最后1个切换为零来获得下一个较小的浮点值:
binary: 00111101110011001100110011001100
value: 0.09999999403953552
下一个较大的浮动值:
binary: 00111101110011001100110011001101
value: 0.10000000149011612
问题是:给定一个浮点数,有没有办法在数据类型float的精度范围内找到最短的小数?
std::string toShortestDecimal(float value)
{
// ? should return "0.1" for 0.09999999403953552
}
编辑:我正在使用this converter。
我目前的想法是从左到右扫描数字以获得第一个差异,然后使用左边的所有内容作为结果。
例如:
00111111110101000111101011100001 = 1.659999966621399
00111111110101000111101011100010 = 1.6600000858306885
由于我向上移动,我可以保持左边第一个更改数字的拉特,即6.结果是1.66是可能的输出。现在我需要在另一个方向重复这个。这可以保证给出正确的结果吗?
另一个问题是当指数和尾数都需要改变时,如何将浮点数增加到最近的邻居。
答案 0 :(得分:1)
这是一个非常低效,可能有漏洞的实现,应该是一个良好的开端:
template<class T>
std::string convert(T value, int precision) {
std::stringstream ss;
ss << std::setprecision(100) << value;
return ss.str();
}
template<class T>
std::string find_shortest(T value) {
auto lower = convert(std::nextafter(value, -std::numeric_limits<T>::infinity()), 100);
auto higher = convert(std::nextafter(value, std::numeric_limits<T>::infinity()), 100);
int diff_idx = 0;
while (lower[diff_idx] == higher[diff_idx]) ++diff_idx;
lower = lower.substr(0, diff_idx+1);
higher = higher.substr(0, diff_idx+1);
if (std::abs(std::stod(lower.c_str()) - value) <
std::abs(std::stod(higher.c_str()) - value)) return lower;
return higher;
}