linux 内核 浮点运算,ARM64与x86_64浮点运算精度比较
浮点数(floating-point number)是属于有理数中某特定子集的数的数字表示,在计算机中用以近似表示任意某个实数。具体来说,这个实数由一个整数或定点数(即尾数)乘以某个基数(计算机中通常是2)的整数次幂得到,这种表示方法类似于基数为10的科学记数法。
大部分计算机采用二进制(b=2)的表示方法。位(bit)是衡量浮点数所需存储空间的单位,通常为32位或64位,分别被叫作单精度和双精度。
浮点数精度标准有:
IEEE 754
16-bit: Half (binary16)
32-bit: Single (binary32), decimal32
64-bit: Double (binary64), decimal64
128-bit: Quadruple (binary128), decimal128
Extended precision formats
计算机内部表示
Type
Sign
Exponent
Significand field
Total bits
Exponent bias
Bits precision
Number of decimal digits
Half(IEEE 754-2008)
1
5
10
16
15
11
~3.3
Single
1
8
23
32
127
24
~7.2
Double
1
11
52
64
1023
53
~15.9
x86 extended precision
1
15
64
80
16383
64
~19.2
Quad
1
15
112
128
16383
113
~34.0
有一些CPU架构提供更大的浮点数,例如Intel的浮点运算单元8087协处理器(以及其被集成进x86处理器中的后代产品)提供80位长的浮点数,用于存储浮点运算的中间结果。还有一些系统提供128位的浮点数(通常用软件实现)。
对比ARM64与x86_64单精度/双精度浮点运算精度,测试代码如下:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
int main()
{
float a=120.31234567890123456789765;
float b=123.52345678901234567890123;
float c= 1.12345678901234567890123;
float d= 3.09876543210987654321987;
float e,f,g;
double a1=120.31234567890123456789312345678901234567890123456789654;
double b1=123.52345678901234567890152345678901234567890145678945678;
double c1= 1.12345678901234567891234567890152345678989014567894234;
double d1= 3.09876543210987654321234562345623456234562345625678981;
double e1,f1,g1;
unsigned long long l_a=5234567890123456789015234567890123456789014567894567876543219812;
unsigned long long l_b=7234567890123456789015234567890126456789014567894567876543219812;
unsigned long long l_c;
double l_d;
e=b-a;
f=c/d;
g=d-c;
e1=b1-a1;
f1=c1/d1;
g1=d1-c1;
l_c = l_b/l_a;
l_d = (double)l_b/(double)l_a;
printf("n===========Single Float Test===================n");
printf("nb:%f(123.52345678901234567890123)-a:%f(120.31234567890123456789765) = %3.23fn", b,a,e);
printf("c:%f(1.12345678901234567890123)/d:%f(3.09876543210987654321987) = %3.23fn", c,d,f);
printf("d:%f(3.09876543210987654321987)-c:%f(1.12345678901234567890123) = %3.23fn", d,c,g);
printf("n************Double Float Test***************n");
printf("nb1:%f(123.52345678901234567890152345678901234567890145678945678)-a1:%f(120.31234567890123456789312345678901234567890123456789654) = %3.52fn", b1,a1,e1);
printf("c1:%f(1.12345678901234567891234567890152345678989014567894234)/d1:%f(3.09876543210987654321234562345623456234562345625678981) = %3.52fn", c1,d1,f1);
printf("d1:%f(3.09876543210987654321234562345623456234562345625678981)-c1:%f(1.12345678901234567891234567890152345678989014567894234) = %3.52fn", d1,c1,g1);
printf("n<<<<<<<<<<<<<<>>>>>>>>>>>>>>n");
printf("n unsigned long long divide l_b/l_a = %llu n", l_c);
printf("unsinged long long divide to double:%3.52fn", l_d);
return 0;
}
分别在ARM64与x86_64机器上运行,结果表明,两个输出完全一致。说明ARM64单精度/双精度浮点运算结果与x86_64完全一致。
x86_64机器运行结果:
-> ./float_test
===========Single Float Test===================
b:123.523460(123.52345678901234567890123)-a:120.312347(120.31234567890123456789765) = 3.21111297607421875000000
c:1.123457(1.12345678901234567890123)/d:3.098765(3.09876543210987654321987) = 0.36254981160163879394531
d:3.098765(3.09876543210987654321987)-c:1.123457(1.12345678901234567890123) = 1.97530853748321533203125
************Double Float Test***************
b1:123.523457(123.52345678901234567890152345678901234567890145678945678)-a1:120.312346(120.31234567890123456789312345678901234567890123456789654) = 3.2111111101111049492828897200524806976318359375000000
c1:1.123457(1.12345678901234567891234567890152345678989014567894234)/d1:3.0 98765(3.09876543210987654321234562345623456234562345625678981) = 0.3625498004369470117502771699946606531739234924316406
d1:3.098765(3.09876543210987654321234562345623456234562345625678981)-c1:1.123457(1.12345678901234567891234567890152345678989014567894234) = 1.9753086430975308473989571211859583854675292968750000
<<<<<<<<<<<<<<>>>>>>>>>>>>>>
unsigned long long divide l_b/l_a = 6
unsinged long long divide to double:6.0746380502316048577426954580005258321762084960937500
ARM64机器运行结果:
-bash-4.3# /mnt/install_aarch64/bin/gcc -o float_test float_test.c
float_test.c: In function ‘main’:
float_test.c:27:27: warning: integer constant is too large for its type
unsigned long long l_a=5234567890123456789015234567890123456789014567894567876543219812;
float_test.c:28:27: warning: integer constant is too large for its type
unsigned long long l_b=7234567890123456789015234567890126456789014567894567876543219812;
-bash-4.3# ./float_test
===========Single Float Test===================
b:123.523460(123.52345678901234567890123)-a:120.312347(120.31234567890123456789765) = 3.21111297607421875000000
c:1.123457(1.12345678901234567890123)/d:3.098765(3.09876543210987654321987) = 0.36254981160163879394531
d:3.098765(3.09876543210987654321987)-c:1.123457(1.12345678901234567890123) = 1.97530853748321533203125
************Double Float Test***************
b1:123.523457(123.52345678901234567890152345678901234567890145678945678)-a1:120.312346(120.31234567890123456789312345678901234567890123456789654) = 3.2111111101111049492828897200524806976318359375000000
c1:1.123457(1.12345678901234567891234567890152345678989014567894234)/d1:3.0 98765(3.09876543210987654321234562345623456234562345625678981) = 0.3625498004369470117502771699946606531739234924316406
d1:3.098765(3.09876543210987654321234562345623456234562345625678981)-c1:1.123457(1.12345678901234567891234567890152345678989014567894234) = 1.9753086430975308473989571211859583854675292968750000
<<<<<<<<<<<<<<>>>>>>>>>>>>>>
unsigned long long divide l_b/l_a = 6
unsinged long long divide to double:6.0746380502316048577426954580005258321762084960937500
-bash-4.3#
linux 内核 浮点运算,ARM64与x86_64浮点运算精度比较相关推荐
- QEMU启动ARM64 Linux内核
目录 前言 前置知识 virt开发板 ARM处理器家族简介 安装qemu-system-aarch64 安装交叉编译工具 交叉编译ARM64 Linux内核 交叉编译ARM64 Busybox 使用b ...
- 【linux kernel】基于ARM64分析linux内核的链接脚本vmlinux.lds.S
文章目录 一.导读 二.链接器是什么 三.链接脚本 四.linux内核的链接脚本 4-1 头文件包含描述 4-2 参数设置和宏定义描述 4-3 SECTIONS内容分析 五.linux内核的" ...
- linux内核层功能 和核心,Linux内核研发工程师
岗位职责: 1.根据软件技术方案完成对内核特性的深层次改进或全新功能的开发.调试工作: 2.熟练运用各种系统性能分析工具,熟悉性能优化,能够完成子系统级的性能优化工作: 3.参与虚拟化底层技术的研究和 ...
- linux内核是干什么,linux内核开发工程师
岗位描述: 研究Linux内核的实现原理,参与软件技术方案的设计,负责Linux内核新特性的开发工作,解决产品中Linux内核相关的异常和故障,优化Linux内核提升操作系统产品性能指标. 岗位职责: ...
- 深入理解Linux内核使用浮点运算问题
一.早期处理器 由于早期处理器硬件压根没有浮点运算功能, 所以编译器自然不会编译出对应指令, 但是确实有需要的场景, 无论应用程序还是内核驱动, 所有出现了浮点模拟器,具体配置在: 原理很简单, 就是 ...
- 从 Java sleep 来看 arm64 Linux 内核都干了些什么?
使当前正在执行的线程休眠(暂时停止执行)指定的毫秒数,取决于系统计时器和调度器的精度和准确性.线程不会失去任何监视器的所有权. sleep(long millis) 仅仅调用 sleep 带两个参数版 ...
- 【Linux 内核 内存管理】Linux 内核内存布局 ④ ( ARM64 架构体系内存分布 | 内核启动源码 start_kernel | 内存初始化 mm_init | mem_init )
文章目录 一.ARM64 架构体系内存分布 二.Linux 内核启动源码 start_kernel 三.内存初始化源码 mm_init 四.内存初始化源码 mem_init 一.ARM64 架构体系内 ...
- Linux 内核定时器使用 一 低精度定时器
内核定时器是一个数据结构,它告诉内核在用户定义的时间点使用用户定义的参数来执行一个用户定义的函数.其实现位于 <linux/timer.h>中. 内核提供了一组用来声明.注册和删除内核定时 ...
- qemu搭建arm运行linux内核,centos使用qemu搭建ARM64运行环境
准备工作 (1) linux 内核源码, 从github上获取 git clone https://github.com/torvalds/linux make kernelversion (2) 交 ...
- linux 内核定时器精度_高精度时钟工作机制简介
1. 为什么会有高精度时钟 既然提到高精度,那么其对应的就是低精度,所以高精度时钟是为了解决低精度时钟计时精度不足的问题.举个例子帮助理解,日出而作,日落而息,古人以天为单位,安排劳作和休息.随着生产 ...
最新文章
- 内存中的rank跟bank有什么区别
- 分布式系统关注点(9)——想通关「限流」?只要这一篇
- C# 数据库存储过程的讲解应用
- java 历届试题 合根植物
- uc3842开关电源电路图_详解6款简单的开关电源电路设计原理图
- 【软件体系结构】考点整理
- Html5 + fromData + Spring MVC 单文件、多文件上传
- java net 安卓_Java和Android Http连接程序:使用java.net.URL 下载服务器图片到客户端...
- iOS:特殊符号大全
- php递归函数名字,php递归示例 php递归函数代码
- 达摩达兰论估价pdf_应用公司理财PDF下载_(美)阿斯瓦斯・达摩达兰_机械工业出版社_会计_管理_零度图书网...
- IBM8800存储,光钎交换机384B,主机Linux,二代支付前置
- 内蒙古自治区及其盟市行政单位中英文名称对照表
- 4.7 使用色相/饱和度命令调整图像的色彩 [原创Ps教程]
- SpringBoot-SSMP超详细整合案例
- React Native入门-实战解析(上)
- 联想电脑拯救者y7000触摸屏失灵的修复方法
- Icon图标制作(转化)工具
- 利用h5小游戏来做营销
- php 顺时针打印矩阵,这题
热门文章
- 常用系统修复软件绿色工具包
- Shapefile属性操作之改
- PyCharm下载安装以及使用教程
- rabbit原理及项目应用
- linux 命令总结之tr命令
- notepad打开java乱码_notepad打开中文乱码
- 有T2 表中的数据,求出NAME中每组累加 / 每组总数的比例大于0.6 的id 和name
- 计算机配置中什么表示硬盘,硬盘驱动器指示灯一直亮着,教您如果计算机硬盘驱动器指示灯一直亮着怎么办...
- php唤起微信打开网址,点击链接打开微信再跳转到微信内部浏览器的解决方案
- 云览天下,一触即达——QQ 浏览器(android) 设计之路