如何在c++中获取双精度值中的位数
How to get the number of digit in double value in C++?
我试图从双值中获得数字的数量,但它不能正常工作。我试过了:
int main()
{
double value = 123456.05;
std::cout<<"number of digit::"<<((int)std::log10(value ) + 1);
}
输出::
位数::6
如何得到确切的数字数?
假设您只需要此操作用于双字面值,则以下操作即可。
编辑:添加了一个等效函数,适用于double类型的子集。它使用穷举搜索所有合理的方式来显示十进制的双精度,如果您需要这个函数真正尖叫,可能有一些方法可以使它更有效。
#include <iostream>
#include <string.h>
#include <assert.h>
#include <cmath>
struct double_literal {
const char* string_value;
double double_value;
size_t num_digits;
};
#define DOUBLE_LITERAL(x) {#x, x, strlen(#x)};
size_t num_digits(double value){
//Double gives around 15 accurate digits usually.
//Disregarding exponential notation, there are hence only 15 reasonable
//ways to display value, ranging from 15 places in front of the decimal
//to 15 behind. Figure out which of these is best in terms of error,
//and then at the end print out how many digits are needed to display
//the number by removing unecessary zeros.
//Routine currently only handles values within these bounds
//If your value is outside, can scale it with a power of ten before
//using. Special cases for zero and negative values can also be added.
double window_stop = std::pow(10.0, 15);
double window_start = 1 + std::pow(10.0, -15);
assert(value < window_stop);
assert(value > window_start);
size_t best_window = 0;
double best_error = INFINITY;
double pow_ten_window = 1;
for(size_t window = 0; window <= 15; window++, pow_ten_window *= 10){
double rounded = fmod(
std::round(value * pow_ten_window),
window_stop
) / pow_ten_window;
double error = std::abs(rounded - value);
if (error < best_error){
best_error = error;
best_window = window;
}
}
unsigned long long best_rounding = std::llround(
fmod(
value * std::pow(10.0, best_window),
window_stop
)
);
size_t best_digits = std::llround(std::log10(best_rounding) + 1);
//Representation has an integer part => just figure out if we
//need a decimal point
if (best_window > 0){
best_digits++;
}
std::cout << best_window << std::endl;
return best_digits;
}
int main(int argc, char** argv){
struct double_literal literal DOUBLE_LITERAL(123456.05);
std::cout << "number of digit::" << literal.num_digits << std::endl;
//As a function
std::cout << "numbr of digit::" << num_digits(literal.double_value);
}
使用文字,您可以在后面的代码中以多种形式获得文字的值。
该函数也适用于非字面量,但仅适用于双精度数的有限子集。请参阅评论,了解如何将其推广到其他部分。
可以将双精度值转换为字符串:
double value = 123456.05;
std::string s = std::to_string(value);
之后,您需要删除尾随零(因为s == "123456.050000"
现在可能):
s.erase(s.find_last_not_of('0') + 1, std::string::npos);
则获取该字符串的若干个字符:
std::cout<<"number of digit::"<< s.length();
(在本例中,您将把"。"作为数字处理)
因此,下面的程序返回预期的结果:
位数::9
但是这对于整数值并不完美,因为"123"将被表示为"123"。(最后再加一个字符)。因此,对于整数值,最好在获得长度为
之前删除后面的"。"void print_nb_digits(double value) {
std::string s = std::to_string(value);
s.erase(s.find_last_not_of('0') + 1, std::string::npos);
if (!s.empty() && !std::isdigit(s.back()))
s.pop_back();
std::cout<<"number of digit::"<< s.length();
}
double value = 123456.05;
print_nb_digits(value);
在这种情况下,程序也返回value = 123456
的正确结果:
位数::6
相关文章:
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 正在将csv文件读取为双精度矢量
- 我可以信任表示整数的浮点或双精度来保持精度吗
- 如何在C++中的同一函数中使用字符串和双精度
- 特征::矩阵<双精度,1,3> 结构类型函数中的返回类型函数
- 检查是否以特定精度给出双精度
- 转换函数,将 std::数组的双精度作为参数或双精度作为参数单独转换
- C 字符串返回字符串的整数/双精度/长整型值
- C++ 运算符"="重载 - 在 lhs 上获取向量中的所有值,使其等于 rhs 上的双精度值
- 获取长双精度向量的方差
- 有没有办法构造一个 constexpr 函数来获取双精度的位表示
- C++,如何从字符串中获取正确的双精度值
- 在C++中获取大于或等于一个双精度的最小浮点值(以及小于或等于一的最大浮点值)
- C++ 如何获取兰登数以及如何保存带有 ONY 两位小数的双精度
- 在 C++ 中获取长整型和双精度型模数的准确方法
- 在 rapidjson 解析中获取双精度值的原始字符串(或字节)
- 获取完整的双精度值
- 从输入中获取一个数字和一个单位作为双精度和字符串——编程:使用c++的原则和实践
- 从双精度数据类型获取特定整数的方法
- 如何在c++中获取双精度值中的位数