题意及分析:
给定一个字符串(格式为AeB)代表
。
直接求是非常困难的,所以我们反正求,根据M和E的范围打表查找。
首先,我们先分析一下题意及各变量的意义。
如上图所示,这是一个浮点数的二进制存储:
- 绿色的 '1' 代表的是尾数(用m表示)的二进制,尾数的位数(有几个1就几位)用M表示(这个M=8);
(ps:事实上,尾数m前面自动省略了‘0.1’,上图m=0.111111111(“0.1”+“11111111”),此题m=11111111)- 第一位数字 '0' 代表的是尾数的符号;(0为正数,1为负数)
- 后面紫色的 '1' 代表的是指数(用e表示)的二进制,它的位数用E表示。
- 第二个 '0' 代表指数的符号;
所以上图就可以表示为:
转换成十进制为:
此处:m=0.998046875,e=63,M=8,E=6。
了解以上内容后,我们就可以根据M和E的范围进行打表了。
首先我们需要知道几个公式:
这样的话我们就知道十进制的m和e了;
接下来将根据公式求A和B:
两边同时取对数上式可转化为:m和e是已知的,令
那么并且 0 < A < 10,logA<1的,那么B取t的整数部分,logA取t的小数部分即可。
这样就可以通过二维数组遍历查找与A0,B0相等的A[M][E]和B[M][E]。
import java.util.*; public class Main { static double[][] A = new double[20][40]; static long[][] B = new long[20][40]; static void init() { //根据M和E的范围打表。 for (int M = 0; M <= 9; M++) { for (int E = 0; E <= 30; E++) { double m = 1 - Math.pow(2, -1 - M), e = Math.pow(2, E) - 1; double t = Math.log10(m) + e * Math.log10(2); B[M][E] = (long) t; //B取整数部分 A[M][E] = Math.pow(10, t - B[M][E]); //A取小数部分 } } } static Scanner cin = new Scanner(System.in); public static void main(String[] args) { String s = null; init(); while (true) { s = cin.next(); if (s.equals("0e0")) { break; } String[] op = new String[2]; op = s.split("e"); double A0 = Double.parseDouble(op[0]); long B0 = Long.parseLong(op[1]); int ok = 0; for (int M = 0; M <= 9; M++) { for (int E = 1; E <= 30; E++) { if (B0 == B[M][E] && Math.abs(A[M][E] - A0) <= 0.00001) { System.out.println(M + " " + E); ok = 1; break; } if (ok == 1) { break; } } } } } }