浮点数 我在C++中遵循一些OpenGL的初学者教程,但从C程序员开始,我就把很多事情都当作理所当然。因此,我的问题发生在调试将FPS读数打印到输出时。我认为这个方法类似于我头顶上的DebugPrintString,它取了一个字符*基本上我是在打印“FPS:x”。我使用scanf_s将fps值放入字符数组中,但这就是我的问题所在。角色数组必须有多大

浮点数 我在C++中遵循一些OpenGL的初学者教程,但从C程序员开始,我就把很多事情都当作理所当然。因此,我的问题发生在调试将FPS读数打印到输出时。我认为这个方法类似于我头顶上的DebugPrintString,它取了一个字符*基本上我是在打印“FPS:x”。我使用scanf_s将fps值放入字符数组中,但这就是我的问题所在。角色数组必须有多大,c++,floating-point,floating-accuracy,frame-rate,C++,Floating Point,Floating Accuracy,Frame Rate,让我再详细说明一下:我的FPS读数存储为浮点,因为帧数/秒通常不是一个好的数字。所以我的号码可以是60,也可以是59.12345。60只需要2个字节,59.12345需要8个字节(期间为1个字节)。所以我想“哦,好吧,我需要数一数它有多少个数字,没问题!”男孩让我大吃一惊 我提出了一种计算数字的方法,计算小数点左边很容易,首先将其转换为int,去掉小数点,然后除以10(实际上我认为我在那里有一些位移位),然后计算我可以这样做的次数,直到达到0。现在来计算右边的数字,我将乘以10,减去这个数字,直

让我再详细说明一下:我的FPS读数存储为浮点,因为帧数/秒通常不是一个好的数字。所以我的号码可以是60,也可以是59.12345。60只需要2个字节,59.12345需要8个字节(期间为1个字节)。所以我想“哦,好吧,我需要数一数它有多少个数字,没问题!”男孩让我大吃一惊

我提出了一种计算数字的方法,计算小数点左边很容易,首先将其转换为int,去掉小数点,然后除以10(实际上我认为我在那里有一些位移位),然后计算我可以这样做的次数,直到达到0。现在来计算右边的数字,我将乘以10,减去这个数字,直到它达到零。这个方法通常会返回32,我想是的。因此,我在调试中查看了它,结果是,当你乘以浮点时,由于众所周知的精度问题,有效地将数字列向上移动,它只是附加了另一个数字

我在谷歌上搜索了一些主要内容,但在char-str[128]和scanf-if-then-do-strlen(str)减1(空终止符)上找不到任何内容。但我希望有一个更优雅的解决方案。最后,我只是将其转换为int,并允许足够的9999 fps,还添加了一个检查,看看fps是否>9999,但我认为这永远不会发生。比SEG故障更安全:(

TLDR:有没有办法得到浮点中的位数?scanf是怎么做到的

抱歉发了这么长的帖子,我只是想分享我的站>:D


<>编辑:拼写错误

你可以用SpIFTF截断/强迫浮点数到任何你想要的精度。然后问题就消失了。

< P>考虑到C++是我们正在讨论的,为什么不去STL方式?< /P> 小数点后5位精度,可能是可变字符数:

std::stringstream ss;
ss << std::setprecision (5) << std::fixed << f; 
std::string fps = ss.str();
std::stringstream-ss;

ss是每秒帧数。只需在左侧使用三个数字,在右侧使用一个数字,谁会在意浮点表示法认为在十分之一位以下存在什么

编辑以响应第一条注释

如果我们真的在寻找浮点中的位数,我们必须知道浮点是如何工作的。IEEE标准浮点数据类型中表示的精确值有一定数量的位,通常是32或64,它们以标准化的方式分配给您一个设定数量的有效位,以及一些幂指数来放大或缩小。24 bi有效数字的ts以小数形式显示为大约7位。在课程结束时总会有某种形式的截断或舍入错误(比如,当你停止写重复的3时,用十进制写的三分之一总是向下舍入)


也许你的数字在七位或八位之后就停止了,但是机器舍入错误让它意外地继续运行?读取那种数据是没有意义的。

因为浮点数没有以任何精确的方式存储,所以实际上没有任何有效的方法来计算位数。你可能想做的是控制ol浮点提供的数字长度,并使用固定大小的缓冲区

使用
printf()
scanf()
和相关函数,可以通过修改格式类型说明符来指定浮点数的大小。虽然简单的
%f
可能是最常见的,但可以通过在
%
f
之间添加修饰符来更灵活地使用它,例如:

%[width][.precision]f
其中,
[width]
是指数字显示的最小位数(如果超过,则不会截断),而
[.precision]
指定小数点后要显示的确切位数

例如,您可以检查以下程序的输出:

#include <cstdio>

using std::printf;
int main() {
  float f(59.12345);

  printf("[%f]\n", f);    // [59.123451]
  printf("[%15f]\n", f);  // [      59.123451]
  printf("[%1f]\n", f);   // [59.123451]
  printf("[%.2f]\n", f);  // [59.12]
  printf("[%6.2f]\n", f); // [ 59.12]
  printf("[%4.1f]\n", f); // [59.1]
}
#包括
使用std::printf;
int main(){
浮动f(59.12345);
printf(“[%f]\n”,f);//[59.123451]
printf(“[%15f]\n”,f);//[59.123451]
printf(“[%1f]\n”,f);//[59.123451]
printf(“[%.2f]\n”,f);//[59.12]
printf(“[%6.2f]\n”,f);//[59.12]
printf(“[%4.1f]\n”,f);//[59.1]
}
字符数组的确切大小仍然会根据小数点前的值而变化。但只要可以控制宽度和精度,就可以为字符数组分配足够的内存(或将数字拟合到固定长度数组中)应该更简单。

CashCommons的John给出了传统的答案,只需使用printf格式限定符强制指定一定的宽度。我通常发现帧速率的小数点后2位就足够了。它允许您区分30 fps和29.97 fps这两个最常见的值

 sprintf (buffer, "%.2f", fps);
但是如果你想知道最坏的情况是什么,还有一种方法可以知道。结帐

它显示浮点值(32位浮点)尾数中有24位二进制数字,等于7.225位十进制数字,称之为8。加上5位表示指数,1位表示符号,1位表示前导0,1位表示小数点,得到

 1 + 1 + 8 + 5 = 15 characters

为终止null添加空间,您将得到16位数字。

sprintf?这句话是填充文本。对不起,您的意思是什么?太长了?是的,哈哈,对不起:p“递归”需要在他的评论中至少写15个字符。“sprintf?”只有8个。这可能是使用7的最混乱的方式
 1 + 1 + 8 + 5 = 15 characters