❶ float和double型分别怎么存储
C/C++的浮点数据类型有float和double两种。
类型float大小为4字节,即32位,内存中的存储方式如下: 符号位(1 bit) 指数(8 bit) 尾数(23 bit)
类型double大小为8字节,即64位,内存布局如下: 符号位(1 bit) 指数(11 bit) 尾数(52 bit)
符号位决定浮点数的正负,0正1负。
指数和尾数均从浮点数的二进制科学计数形式中获取。
如,十进制浮点数2.5的二进制形式为10.1,转换为科学计数法形式为(1.01)*(10^1),由此可知指数为1,尾数(即科学计数法的小数部分)为01。
根据浮点数的存储标准(IEEE制定),float类型指数的起始数为127(二进制0111 1111),double类型指数的起始数为1023(二进制011 1111 1111),在此基础上加指数,得到的就是内存中指数的表示形式。尾数则直接填入,如果空间多余则以0补齐,如果空间不够则0舍1入。所以float和double类型分别表示的2.5如下(二进制):
符号位
指数
尾数
0
1000 0000
010 0000 0000 0000 0000 0000
0
100 0000 0000
0100 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
❷ IEEE 754啥意思java中float和double的存储方式就是用IEEE 754表示吗通俗一点讲讲,必采纳
IEEE二进制浮点数算术标准(IEEE 754)是最广泛使用的浮点数运算标准,它规定了四种表示浮点数值的方式:单精确度(32位元)、双精确度(64位元)、延伸单精确度(43位元以上,很少使用)与延伸双精确度(79位元以上,通常以80位元实做)。
2.1 实数的IEEE 754表示形式
一个实数V在IEEE 754标准中可以用V=(-1)s×M×2E 的形式表示[3,4],说明如下:
(1)符号s(sign)决定实数是正数(s=0)还是负数(s=1),对数值0的符号位特殊处理。
(2)有效数字M(significand)是二进制小数,M的取值范围在1≤M<2或0≤M<1。
(3)指数E(exponent)是2的幂,它的作用是对浮点数加权。
2.2 浮点格式
浮点格式是一种数据结构,它规定了构成浮点数的各个字段,这些字段的布局,及其算术解释[2]。IEEE 754浮点数的数据位被划分为3个字段,对以上参数值进行编码:
(1)一个单独的符号位s直接编码符号s。
(2)k位的偏置指数e(e=ek-1…e1e0)编码指数E,移码表示。
(3)n位的小数f(fraction)(f=fn-1…f1f0)编码有效数字M,原码表示。
2.3 浮点数的分类
根据偏置指数e的值,被编码的浮点数可分成三种类型。
(1)规格化数
当有效数字M在范围1≤M<2中且指数e的位模式ek-1…e1e0既不全是0也不全是1时,浮点格式所表示的数都属于规格化数。这种情况中小数f(0≤f<1 ) 的二进制表示为0. fn-1…f1f0。有效数字M=1+f,即M=1. fn-1…f1f0 (其中小数点左侧的数值位称为前导有效位) 。我们总是能调整指数E,使得有效数字M在范围1≤M<2中,这样有效数字的前导有效位总是1,因此该位不需显示表示出来,只需通过指数隐式给出。
需要特别指出的是指数E要加上一个偏置值Bias,转换成无符号的偏置指数e,也就是说指数E要以移码的形式在存放计算机中。且e、E和Bias三者的对应关系为e=E+Bias,其中Bias=2k-1-1。
(2)非规格化数
当指数e的位模式ek-1…e1e0全为零(即e=0)时,浮点格式所表示的数是非规格化数。这种情况下,E=1-Bais,有效数字M=f=0. fn-1…f1f0 ,有效数字的前导有效位为0。
非规格化数的引入有两个目的。其一是它提供了一种表示数值0的方法,其二是它可用来表示那些非常接近于0.0的数。
(3)特殊数
当指数e的位模式ek-1…e1e0全为1时,小数f的位模式fn-1…f1f0全为0(即f=0)时,该浮点格式所表示的值表示无穷,s=0 时是+∞,s=1时是-∞。
当指数e的位模式ek-1…e1e0全为1时,小数f的位模式fn-1…f1f0不为0(fn-1、…、f1、f0、至少有一个非零即f≠0)时,该浮点格式所表示的值被称为NaN(Not a Number)。比如当计算 或∞-∞时用作返回值,或者用于表示未初始化的数据。
3 IEEE 754浮点存储格式
与浮点格式对应,浮点存储格式规定了浮点格式在存储器中如何存放。IEEE标准定义了这些浮点存储格式,但具体选择哪种存储格式由实现工具(程序设计语言)决定。
汇编语言软件有时取决于所使用的存储格式,但更高级的语言通常仅处理浮点数据类型的语言概念。这些浮点数据类型在不同高级语言中有不同的名字,相应的IEEE格式如表1。
表1 IEEE 格式和语言类型
IEEE精度 C,C++ FORTRAN
单精度 float REAL or REAL*4
双精度 double DOUBLE PRECISION or REAL*8
扩展双精度 long double REAL*16 [仅适用于SPARC和PowerPC]
IEEE 754标准准确地定义了单精度和双精度浮点格式,并为这两种基本格式的分别定义了扩展格式,表1里扩展双精度格式是IEEE标准定义的扩展双精度类中的一种。
下面详细讨论在Intel x86和SPARC平台上使用的三种IEEE浮点存储格式。
3.1 单精度格式
IEEE单精度浮点格式共32位,包含三个构成字段:23位小数f,8位偏置指数e,1位符号s。将这些字段连续存放在一个32位字里,并对其进行编码。其中0:22位包含23位的小数f; 23:30位包含8位指数e;第31位包含符号s。如图1所示。
图1 单精度存储格式
一般地,32位字的第0位存放小数f的最低有效位LSB(the least significant bit),第22位存放小数f的最高有效位MSB(the most significant bit);第23位存放偏置指数的最低有效位LSB,第30位存放偏置指数的最高有效位MSB;最高位,第31位存放符号s。
3.2 双精度格式
IEEE双精度浮点格式共64位,占2个连续32位字,包含三个构成字段:52位的小数f,11位的偏置指数e,1位的符号位s。将这2个连续的32位字整体作为一个64位的字,进行重新编号。其中0:51位包含52位的小数f;52:62位包含11位的偏置指数e;而最高位,第63位包含符号位s。如图2所示。
图 2 双精度浮点数的存储格式
f[31:0]存放小数f的低32位,其中第0位存放整个小数f的最低有效位LSB,第31位存放小数f的低32位的最高有效位MSB。
在另外的32位的字里,第0 到19位,即f[51:32],存放小数f的最高的20位,其中第0位存放这20位最高有效数中的最低有效位LSB,第19位存放整个小数f的最高有效位MSB。第20到30位,即e[52:62],存放11位的偏置指数e,其中第20位存放偏置指数的最低有效位LSB,第30位存放最高有效位MSB。最高位,第31位存放符号位s。
在Intel x86结构计算机中,数据存放采用小端法(little endian),故较低地址的32位的字中存放小数f的f[31:0]位。而在在SPARC结构计算机中,因其数据存放采用大端法(big endian),故较高地址的32位字中存放小数f的f[31:0]位。
3.3 扩展双精度格式
⑴ 扩展双精度格式(SPARC 结构计算机)
该4倍精度浮点环境符合IEEE关于扩展双精度格式的定义。该浮点环境的4倍精度浮点格式共128位,占4个连续32位字,包含3个构成字段:112位的小数f,15位的偏置指数e,和1位的符号s。将这4个连续的32位字整体作为一个128位的字,进行重新编号。其中0:110位包含小数f;112:126位包含偏置指数e;第127位包含符号位s。如图3所示。
在SPARC结构计算机中,地址最高的32位字存放小数的32位最低有效位,即f[31:0];但是在PowerPC结构计算机中,却是地址最低的32位字存放这些位。
紧邻的两个32位字(在SPARC机中向下计算,在PowerPC机中向上计算)分别存放f[63:32]和f[95:64]。
最后一个字的第0到15位存放小数的最高16位,即f[111:96]。其中第0位存放该16位的最低有效位,第15位存放整个小数f的最高有效位。第16到30位存放15位的偏置指数e,其中第16位存放偏置指数的最低有效位,第30位存放它的最高有效位。最高位,第31位存放符号s。
图 3 扩展双精度存储格式 (SPARC 结构计算机)
⑵ 扩展双精度格式(Intel x86结构计算机)
该浮点环境双精度扩展格式符合IEEE双精度扩展格式的定义。该浮点环境的扩展双精度格式共80位,占3个连续32位字,包含四个构成字段:63位的小数f,1位显式前导有效位(explicit leading significand bit)j,15位偏置指数e,和1位符号位s。将这3个连续的32位字整体作为一个96位的字,进行重新编号。其中0:63包含63位的小数f,第63位包含前导有效位j,64:78位包含15位的偏置指数e,最高位第79位包含符号位s。
在Intel结构系计算机中,这些字段依次存放在十个连续的字节中。但是,由于 UNIX System V Application Binary Interface Intel 386 Processor Supplement (Intel ABI) 要求双精度扩展参数,从而占用堆栈中3个相连地址的32位字,其中最高一个字的高16位未被使用,如图4所示。
图4 扩展双精度存储格式(Intel x86结构计算机)
地址最低的32位字存放小数f的低32位,即f[31:0]。其中第0位存放整个小数f的最低有效位LSB 第31位存放小数低32位的最高有效位MSB。
地址居中的32位字,第0到30位存放小数f的31位最高位,即f[62:32]。其中第0位存放31位最高小数位的最低有效位LSB,第30位存放整个小数的最高有效位,地址居中的32位字的最高位第31位存放显式的前导有效位j。
地址最高32位字里,第0到14位存放15位的偏置指数e,第0位存放偏置指数的最低有效位LSB,第14位存放最高有效位MSB,第15位存放符号位s。虽然地址最高的32位字的高16位在Intel x86结构系列机种未被使用,但他们对符合Intel ABI的规定来说,是必需的。
4 总结
以上讨论了Intel x86、Power PC和SPARC平台上使用的三种IEEE 754浮点数格式及其存储格式,下面对浮点数的相关参数进行总结,具体见表2。
表2 IEEE 浮点格式参数总结
参数 浮点格式
单精度 双精度 扩展双精度(Intel x86) 扩展双精度(SPARC)
小数f宽度n 23 52 63 112
前导有效位 隐含 隐含 显式 隐含
有效数字M精度p 24 53 64 113
偏置指数宽度k 8 11 15 15
偏置值Bias +127 +1023 +16383 +16383
符号位宽度 1 1 1 1
存储格式宽度 32 64 80 128
参考文献
[1] David Goldberg with Doug Priest. What Every Computer Scientist Should Know about Floating-Point Arithmetic. http://grouper.ieee.org/
[2] Sun Corporation.Numerical Computation Guide, pp1-11. http://docs.sun.com
[3] Randal E.Bryant,David O'Hallaron. Computer Systems Aprogrammer’s Perspective(英文版) [M] .北京:电子工业出版社,2004
[4]David A. Patterson, John L. Hennessy.Computer Organization & Design: The Hardware/Software Interface. (英文版 第二版) [M] . 北京:机械工业出版社,1999.275~321
❸ 浮点类型是如何存储的
计算机中最小的存储单位是bit只能保存0和1,整数在内存中如何存储我们都知道,将要存储的数字转成2进制即可
用windows自带的计数器可以方便的查看整数对应的2进制值
如:
byte类型(单字节)
那浮点类型是如何用这么少的字节(如float 4字节)表示这么大(float 最大 3.4028235E38)的数字呢?
浮点数,是属于有理数中某特定子集的数的数字表示,在计算机中用以近似表示任意某个实数。具体的说,这个实数由一个整数或定点数(即尾数)乘以某个基数(计算机中通常是2)的整数次幂得到,这种表示方法类似于基数为10的科学计数法。
科学计数法是一种记数的方法。把一个数表示成a与10的n次幂相乘的形式(1≤|a|<10,a不为分数形式,n为整数),这种记数法叫做科学计数法。当我们要标记或运算某个较大或较小且位数较多时,用科学计数法免去浪费很多空间和时间。
这也是一种目前最常用的浮点数标准!为许多CPU与浮点运算器所采用。
简单的说就是将一个浮点数字拆成3个部分(符号部分、指数部分、小数部分) 存储在连续的bit中,类似科学计数法。
用 {S,E,M}来表示一个数 V 的,即 V =(-1)S × M × 2E ,如下:
其中:
其中d.dd...d 为有效数字,β为基数,e 为指数
有效数字中 数字的个数 称为 精度 ,我们可以用 p 来表示,即可称为 p 位有效数字精度。
每个数字 d 介于 0 和基数 β 之间,包括 0。
对十进制的浮点数,即基数 β 等于 10 的浮点数而言,上面的表达式非常容易理解。
如 12.34,我们可以根据上面的表达式表达为:
1×10 1 + 2×10 0 + 3×10 -1 + 4×10 -2
其规范的浮点数表达为: 1.234×10 1 。
但对二进制来说,上面的表达式同样可以简单地表达。
唯一不同之处在于:二进制的 β 等于 2,而每个数字 d 只能在 0 和 1 之间取值。
如二进制数 1001.101 ,我们可以根据上面的表达式表达为:
1×2 3 + 0×2 2 + 0×2 1 + 1×2 0 + 1×2 -1 + 0×2 -2 + 1×2 -3
其规范浮点数表达为: 1.001101×2 3 。
二进制数 1001.101 转成十进制如下:
由上面的等式,我们可以得出:
向左移动二进制小数点一位相当于这个数除以 2,而向右移动二进制小数点一位相当于这个数乘以 2。
如 101.11 = 5又3/4 (5.75),向左移动一位,得到 10.111 = 2又7/8 (2.875)。
除此之外,我们还可以得到这样一个基本规律:
一个十进制小数要能用浮点数精确地表示,最后一位必须是 5(当然这是必要条件,并非充分条件)。
如下面的示例所示:
基本换算方法:
将10进制的数拆分成整数和小数两个部分
整数部分除以2,取余数;小数部分乘以2,取整数位。
示例:
将十进制 1.1 转成 二进制
整数部分:1
1
小数部分:0.1
二进制形式表示为:
1.000110011001100110011...
再加上整数1,约等于:
1.099609375
计算的位数越多越精确
注意:
二进制小数不像整数一样,只要位数足够,它就可以表示所有整数。
在有限长度的编码中,二进制小数一般无法精确的表示任意小数,比如十进制小数0.2,我们并不能将其准确的表示为一个二进制数,只能增加二进制长度提高表示的精度。
根据 IEEE 754 浮点“双精度格式”位布局。
如果参数是正无穷大,则结果为 0x7ff0000000000000L。
如果参数是负无穷大,则结果为 0xfff0000000000000L。
如果参数是 NaN,则结果为 0x7ff8000000000000L。
根据 IEEE 754 浮点“单一格式”位布局。
如果参数为正无穷大,则结果为 0x7f800000。
如果参数为负无穷大,则结果为 0xff800000。
如果参数为 NaN,则结果为 0x7fc00000。
这里以 double类型说明
将一个浮点数与上面的掩码进行与运算,即可得到对应的 符号位、指数位、尾数位 的值。
1.000110011001100110011...
所以存为:
0 01111111111 000110011001100110011...
根据 IEEE 754 规范
在二进制,第一个有效数字必定是“1”,因此这个“1”并不会存储。
单精和双精浮点数的有效数字分别是有存储的23和52个位,加上最左边没有存储的第1个位,即是24和53个位。
通过计算其能表示的最大值,换十进制来看其精度:
浮点运算很少是精确的,只要是超过精度能表示的范围就会产生误差。而往往产生误差不是因为数的大小,而是因为数的精度。
我自己理解为分两种情况(这个不一定是对)
通过上面的转换示例,我们知道小数的二进制表示一般都不是精确的,在有限的精度下只能尽量的表示近似值
值本身就不是精确的,再进行计算就很可能产生误差
输出:
0.1
原始值: 0 01111111011
指数:1019 -1023 = -4
二进制形式:
0.0001
0.2
原始值:0 01111111100
指数:1020 -1023 = -3
二进制形式:
0.00
0.3
原始值:0 01111111101
指数:1021 = -2
二进制形式:
0.00
二进制加法运算
这里用float验证,float最大的精度是8位数
对于不能精确的表示的数,采取一种系统的方法:找到“最接近”的匹配值,它可以用期望的浮点形式表现出来,这就是舍入。
对于舍入,可以有很多种规则,可以向上舍入,向下舍入,向偶数舍入。如果我们只采用前两种中的一种,就会造成平均数过大或者过小,实际上这时候就是引入了统计偏差。如果是采用偶数舍入,则有一半的机会是向上舍入,一半的机会是向下舍入,这样子可以避免统计偏差。而 IEEE 754 就是采用向最近偶数舍入(round to nearest even)的规则。
(这段是网上抄的)
这里以java语言示例,用大端的方式示例(网络序)
java中是以大端模式存储的,java对我们屏蔽了内部字节顺序的问题以实现跨平台!
实际在不同的cpu架构下,存储方式不同,我们常用的X86是以小端的模式存储的。
网络传输一般采用大端序,也被称之为网络字节序,或网络序。IP协议中定义大端序为网络字节序。
输出:
❹ 读取和保存一个二维double数组用Java语言如何做
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class NewTxt {
public static void main(String[] args) throws IOException {
int n = 5; //N*N数组
double[][] arr = new double[n][n]; //插入的数组
double[][] arr2 = new double[n][n];; //读取出的数组
//数组初始化,随机生成的[0,100)之间的double数
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
arr[i][j] = Math.random()*100;
System.out.println(arr[i][j]);
}
}
File file = new File("d:\\array.txt"); //存放数组数据的文件
FileWriter out = new FileWriter(file); //文件写入流
//将数组中的数据写入到文件中。每行各数据之间TAB间隔
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
out.write(arr[i][j]+"\t");
}
out.write("\r\n");
}
out.close();
BufferedReader in = new BufferedReader(new FileReader(file)); //
String line; //一行数据
int row=0;
//逐行读取,并将每个数组放入到数组中
while((line = in.readLine()) != null){
String[] temp = line.split("\t");
for(int j=0;j<temp.length;j++){
arr2[row][j] = Double.parseDouble(temp[j]);
}
row++;
}
in.close();
//显示读取出的数组
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
System.out.print(arr2[i][j]+"\t");
}
System.out.println();
}
}
}
❺ java中double类数组要怎样才能精确到有几位小数点
double的表示方式如下:
符号位(1位)
|
指数(11位,1位符号位+10位指数位)
|
尾数(52位)
存储方式是按照浮点的形式存储,所以不存在整数部分和小数部分。比如1678.3456
=
1.6783456
*
10^3,但计算机只认识0、1,所以要将其转化成二进制小数,我们不管转换后的结果如何,转换后得到的浮点数形式肯定是这种1.xxxxxx
*
2
^
y,其中xxxxxx表示小数部分,就是尾数,而小数点前面始终是1,可以不存储,y就是指数部分。
所以上面的1.xxxxxx
*
2^y在计算机中就表示为:
0
|
y
+
127
|
xxxxxx
最前面的符号位为0表示正;指数存储时要加上127;xxxxxx就是尾数。
float的表示方法类似,只是位数不一样,如下:
符号位(1位)
|
指数(8位)
|
尾数(23位)
❻ Java 中Double的疑问
你的理解是错误的,double型是64位,但是表示方法和整数是不一样的。你用整数的想法去理解浮点数,肯定会出错啦。给你看下我做过的笔记,你理解下:
存储布局就是一个浮点数在内存中如何表示.我们知道浮点数有float和double,前者是4个字节也就是32位,后者是8个字节也就是64位.布局分别为:
符号 指数 小数部分 偏移附加(bias)
单精度 1[31] 8[30-23] 23[22-00] 127
双精度 1[63] 11[62-52] 52[51-00] 1023
中括号内为位的编号范围,外面为该部分所占有的位的数量.偏移附加不属于位表示的内容,是一个常量,稍后解释.
符号只有一位:0-表示正数 1-表示负数
指数部分:用指数部分的值(8位/11位,unsigned)的值 减去 偏移附加 得到该数实际的指数 例如值为200,实际指数为73=200-127.对于双精度的double来说常量bias=1023
尾数:尾数是什么?对于一个科学计数法来讲,形式象这样的 L.M×BE,那么这个L.M就是所谓的尾数(mantisa).它由一个起始位和一个小数部分组成.