UVa 11809 Floating-Point Numbers (浮点数)

博客详细介绍了浮点数的二进制存储方式,包括尾数和阶码的组成,并针对UVa 11809题目,提出了用打表方法解决最大浮点数问题的策略。通过预先计算每个尾数位数M和阶码位数E对应的最大浮点数,然后利用对数进行转换,简化计算,避免了大量重复计算。同时,博客还讲解了如何使用sscanf函数从字符串中提取所需信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


题意:

先介绍了浮点数的存储---用二进制数存储。浮点数(n)由尾数(mantissa)和阶码(exponent)组成。假设尾数和阶码的位数分别为M和E。按从左至右的顺序,首先是尾数的符号位(0代表正数,1代表负数),接下来是M位尾数部分,由于存储时尾数部分值一定是属于区间[0.5,1),所以M位尾数部分的第一位也就是整体的第二位一定是1。当M位尾数存储完了,第M+1位是阶码的符号位(0代表正数,1代表负数)。然后剩余E位用以保存阶码值。

例如:当M=8,E=6时,可以表示的最大浮点数(二进制)是

利用二进制和十进制的转化规则可以将之转化为:

现在给出一个最大浮点数(用科学计数法AeB表示,且A有效数字15位),问存储时的尾数位数M和阶码位数E个位多少?

其中M取值区间[0,9],E取值区间[1,30]。

测试数据大概300行,0e0结束输入。

分析:

显然对于300行输入数据而且E的结果很可能很大,如果一个一个计算的话,会出现大量重复计算。可以用打表的方法:

预处理每个M和每个E对应的最大浮点数是多少,共300种匹配,然后对于每个输入,查找即可。

a[i][j]表示尾数位数为i,阶码位数为j时存储的最大浮点数。最大浮点数时,除了符号位其余位上都是1。

尾数部分存储数值为m[i],阶码部分存储数值为e[i][j]。通过二进制和十进制转换可得:m[i]=1-(1/2)^(i+1);e[j]=2^j-1;且a[i][j]=m[i]*2^(e[j])

但是如果这样直接存储数值太大了,所以取对数可得a[i][j]=>log10(m[i])+e[j]*log10(2),这样就可以打表了。

如果输入用AeB即A*10^B表示的话,也取对数可得log10(A)+B=t;

对于每个输入只需查找a[i][j]==t,输出对应的m[i]和e[j]即可。
至于A,B如何获取可以用sscanf函数。

sscanf函数的用法:

  sscanf() - 从一个字符串中读进与指定格式相符的数据. 
  函数原型: 
  Int sscanf( string str, string fmt, mixed var1, mixed var2 ... ); 
  int scanf( const char *format [,argument]... ); 
  说明: 
  sscanf与scanf类似,都是用于输入的,只是后者以屏幕(stdin)为输入源,前者以固定字符串为输入源。 

### MATLAB 输入参数必须可转换为浮点数的解决方案 当遇到 `input arguments must be convertible to floating-point numbers` 错误时,通常是因为传递给函数的参数不是有效的数值类型。为了修复此问题,可以采取以下几种方法: #### 1. 检查数据类型 确保所有输入变量都是数值型或能够被转换成双精度浮点数 (double) 类型的数据。可以通过 `class()` 函数来验证变量的具体类别。 ```matlab if ~isnumeric(x) || ~isa(x, 'double') error('Input argument ''x'' is not a valid numeric type.'); end ``` 如果发现某些变量并非预期中的数值形式,则应先将其转换再继续操作[^1]。 #### 2. 使用 str2double 进行字符串到数字的转换 对于由字符组成的数组或其他非标准格式存储起来的实际数值,在调用目标函数之前应当尝试利用内置命令如 `str2double()` 来完成必要的转型工作。 ```matlab y = str2double(str); % 如果 y 返回 NaN 表明无法成功解析该串成为合法实数 if isnan(y) warning('Conversion failed'); else disp(['Converted value:', num2str(y)]); end ``` #### 3. 处理缺失值与异常情况 有时也会因为存在未定义元素(NaN)、无穷大(Inf)等原因而触发上述报错提示;因此建议提前过滤掉这些特殊情形下的记录项后再执行后续计算逻辑。 ```matlab data(isnan(data)) = 0; % 将所有的 NaN 替换成零 data(~isfinite(data)) = 0;% 或者处理其他类型的非法数值 ``` 通过以上措施一般能有效规避因不当传参所引发的相关运行期错误消息显示出来[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值