深入理解大数与高精度数的处理问题

 更新时间:2013年05月24日 16:56:27   作者:  
本篇文章是对大数与高精度数的处理进行了详细的分析介绍,需要的朋友参考下
float和double型数据分别是单精度和双精度型数,他们的取值分别是3.4E+10的负38次方到3.4E+10的38次方,和1.7E+10的负308次方到1.7E+10的308次方。

那么对于float而言,只有6-7位的有效数字,怎么能装下可达3.4*10^(-38)这么大的数呢?同理,15-16位的double型,也无法装下1.7*10^(-308)这么大的数啊?

回答: float 6-7位指的是有效数字的位数(精度),而不是数值大小。例如,3.14159267有9位有效数字,数值却在3~4之间,而350有3位数字,数值却在300~400之间。所以说float数能达到3.4E+10,但是它的有效数字位数只能达到6-7位,如果3.14159267赋值给一个float变量,那么精度将会丢失。例如
复制代码 代码如下:

float a=3234567.1;
float b=3234567;
if( a==b )
    printf("YES");
else
    printf("NO");

将输出YES,因为a末尾的11超出了float 只能达到6-7位的精度。(如果a=1234567.1;b=3234567)输入结果将是NO,为什么呢?这就要我们分析:超出精度的部分怎么处理?不是四舍五入,而是二进制位的丢失。所以说有时候能达到6位的精度,有时候能达到7位的精度,取决于该数的二进制表示。

那么我们就想怎么表示超长位数,超大精度的数字呢?
比如123456789123456789123456789(超长30位的大整数);
比如3.14159012345678901234567890123(超高精度30位的小数),这么长的数字,long float都存不下来,这就要借助于“字符串”或者“字符数组”了。

unsigned __int64 n;
无符号__int64类型的变量n,最大值超过了1234567892345678912(20位),可达到约1.8E+19,平常来说应该够用了。

但是__int64类型的数据不能用C++里面的cout来输出,应该是cout没有重载这个类型,如果用printf来输出,显然%d, %f, %l都无法满足20位的精度,网上查到VC6下可以用printf("%I64d\n", n);但是支持的位数不超过20,经我测试,大概超过9.23E+18 输出的结果就会出错了。那么最好的办法是将“长位数”转换成字符串,如下:
复制代码 代码如下:

char buffer[65];
printf("%s", _ui64toa(n, buffer,10) );

函数_ui64toa就是负责将n转换成字符串的,存入字符数组buffer[65]中,10代表转换成10进制。

数字转换为字符串,参考程序如下:
复制代码 代码如下:

#include <stdlib.h>
#include <stdio.h>
int main( void )
{
   char buffer[65];
   int r;
   for( r=10; r>=2; --r )
   {
     _itoa( -1, buffer, r );
     printf( "base %d: %s (%d chars)\n", r, buffer, strlen(buffer) );
   }
   printf( "\n" );
   for( r=10; r>=2; --r )
   {
     _i64toa( -1L, buffer, r );
     printf( "base %d: %s (%d chars)\n", r, buffer, strlen(buffer) );
   }
   printf( "\n" );
   for( r=10; r>=2; --r )
   {
     _ui64toa( 0xffffffffffffffffL, buffer, r );
     printf( "base %d: %s (%d chars)\n", r, buffer, strlen(buffer) );
   }
}


复制代码 代码如下:

Output
base 10: -1 (2 chars)
base 9: 12068657453 (11 chars)
base 8: 37777777777 (11 chars)
base 7: 211301422353 (12 chars)
base 6: 1550104015503 (13 chars)
base 5: 32244002423140 (14 chars)
base 4: 3333333333333333 (16 chars)
base 3: 102002022201221111210 (21 chars)
base 2: 11111111111111111111111111111111 (32 chars)

base 10: -1 (2 chars)
base 9: 145808576354216723756 (21 chars)
base 8: 1777777777777777777777 (22 chars)
base 7: 45012021522523134134601 (23 chars)
base 6: 3520522010102100444244423 (25 chars)
base 5: 2214220303114400424121122430 (28 chars)
base 4: 33333333333333333333333333333333 (32 chars)
base 3: 11112220022122120101211020120210210211220 (41 chars)
base 2: 1111111111111111111111111111111111111111111111111111111111111111 (64 chars)

base 10: 18446744073709551615 (20 chars)
base 9: 145808576354216723756 (21 chars)
base 8: 1777777777777777777777 (22 chars)
base 7: 45012021522523134134601 (23 chars)
base 6: 3520522010102100444244423 (25 chars)
base 5: 2214220303114400424121122430 (28 chars)
base 4: 33333333333333333333333333333333 (32 chars)
base 3: 11112220022122120101211020120210210211220 (41 chars)
base 2: 1111111111111111111111111111111111111111111111111111111111111111 (64 chars)

PS:可以用这个函数来将10进制整数转换成二进制字符串;
复制代码 代码如下:

int main( void )
{
   char buffer[65];
   _itoa( 12, buffer, 2 );
   printf( "base %d: %s (%d chars)\n", r, buffer, strlen(buffer) );
}

还有一种方法是自己定义字符数组存放超长位数的数,小数点也是可以解决的,然后自己定义这些字符串形式的超长数之间的运算法则并重载运算符,据说这样做运算效率还是蛮高的。

相关文章

  • 使用c++实现OpenCV绘制旋转矩形图形

    使用c++实现OpenCV绘制旋转矩形图形

    这篇文章主要给大家介绍了使用c++实现OpenCV绘制图形旋转矩形的方法案例,通过图文及代码形式进行了详细的描述,有需要的朋友可以参考下,希望可以有所帮助
    2021-08-08
  • C语言之整数划分问题(递归法)实例代码

    C语言之整数划分问题(递归法)实例代码

    这篇文章主要介绍了C语言之整数划分问题(递归法)实例代码的相关资料,需要的朋友可以参考下
    2017-02-02
  • C语言编程大小端问题示例详解教程

    C语言编程大小端问题示例详解教程

    这篇文章主要为大家介绍了C语言编程大小端问题解决的示例内容详解教程,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2021-11-11
  • C语言数字图像处理之图像缩放

    C语言数字图像处理之图像缩放

    这篇文章主要为大家详细介绍了C语言数字图像处理之图像缩放,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • 解析四方定理的应用

    解析四方定理的应用

    所有自然数至多只要用四个数的平方和就可以表示
    2013-05-05
  • 一篇文章带你了解C/C++的回调函数

    一篇文章带你了解C/C++的回调函数

    这篇文章主要为大家介绍了C/C++的回调函数,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-01-01
  • 使用C语言解决字符串全排列问题

    使用C语言解决字符串全排列问题

    这篇文章主要介绍了使用C语言解决字符串全排列问题,文中包括了一道ACM相关的竞赛题目作为实例,需要的朋友可以参考下
    2015-08-08
  • 利用QDir实现删除选定文件目录下的空文件夹

    利用QDir实现删除选定文件目录下的空文件夹

    这篇文章主要为大家详细介绍了如何利用QDir实现删除选定文件目录下的空文件夹功能,文中的示例代码讲解详细,感兴趣的小伙伴可以动手尝试一下
    2022-08-08
  • Visual Studio 2019安装、测试创建c语言项目(图文教程)

    Visual Studio 2019安装、测试创建c语言项目(图文教程)

    这篇文章主要介绍了Visual Studio 2019安装、测试创建c语言项目,Visual Studio 2019是完全免费的,而且安装比较简单,现在把安装步骤分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2020-03-03
  • C++ boost scoped_ptr智能指针详解

    C++ boost scoped_ptr智能指针详解

    智能指针是一种像指针的C++对象,但它能够在对象不使用的时候自己销毁掉。虽然STL提供了auto_ptr,但是由于不能同容器一起使用(不支持拷贝和赋值操作),因此很少有人使用。它是Boost各组件中,应用最为广泛的一个
    2022-11-11

最新评论