首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将数值转换为内存中的标准化双精度,反之亦然?

问如何将数值转换为内存中的标准化双精度,反之亦然?
EN

Stack Overflow用户
提问于 2019-05-24 08:49:15
回答 1查看 369关注 0票数 1

我的主要目的是编写一个转换函数:

  • (十进制)内存中标准化双精度的数值
  • 内存中的规范化双精度为(十进制)数值

即,

代码语言:javascript
复制
from10toNdp(86.125) # 0100000001010101100010000000000000000000000000000000000000000000 (sign|exponent|significand)

fromNdpTo10(0100000001010101100010000000000000000000000000000000000000000000) # 86.125

在创建from10toNdp和fromNdpTo10的过程中,我做了以下工作。

我写了一些助手:

代码语言:javascript
复制
from10to2 <- function(decimalnumber) {
  binaryvector <- rep(0, 1 + floor(log(decimalnumber, 2)))
  while (decimalnumber >= 2) {
    power <- floor(log(decimalnumber, 2))
    binaryvector[1 + power] <- 1
    decimalnumber <- decimalnumber - 2^power  }
  binaryvector[1] <- decimalnumber %% 2
  paste(rev(binaryvector), collapse = "")}
from10to2(8) # "1000"

from10to2函数对于小于2^53 = 9.007199e15的整数(即对于存储为双倍的整数也适用;对于大于2147483647的整数也有效);对于大于2^53的数字,它开始丢失数字。

EXAMPLE1:将0.3位标准化双精度数字转换为64位

符号: 0:波兹格;1:否定

代码语言:javascript
复制
sprintf("%a", 0.3) # ("0x1.3333333333333p-2")16
library(BMS)
BMS::hex2bin("3333333333333") # (0011001100110011001100110011001100110011001100110011)2=significand=(3333333333333)16

由于sprintf输出的最后三个"p-2“和"BiasedExponent=RealExponent+1023bias”(偏差:2^(11-1)-1= 1023),指数(11位)是-2+1023=1021。

代码语言:javascript
复制
from10to2(1021) # ("01111111101")2

双精度存储:

01111111101 - 0011001100110011001100110011001100110011001100110011

符号x指数

EXAMPLE2:转换-2.94到64位标准化双精度数字:

符号: 0:波兹格;1:否定

代码语言:javascript
复制
sprintf("%a", -2.94) # "-0x1.7851eb851eb85p+1"
library(BMS)
BMS::hex2bin("7851eb851eb85") # (0111100001010001111010111000010100011110101110000101)2=significand=(7851eb851eb85)16

由于sprintf输出的最后三个"p+1“和"BiasedExponent=RealExponent+1023bias”(偏差:2^(11-1)-1= 1023),指数(11位)是1+1023=1024。

代码语言:javascript
复制
from10to2(1024) # ("10000000000")2

双精度存储:

1- 10000000000 - 0111100001010001111010111000010100011110101110000101

符号x指数

EXAMPLE3:将86.125位转换为64位规范化的双精度数字:

符号: 0:波兹格;1:否定

代码语言:javascript
复制
sprintf("%a", 86.125) # "0x1.588p+6"
library(BMS)
BMS::hex2bin("588") # (010110001000)2=significand=(588)16

由于sprintf输出的最后三个"p+6“和"BiasedExponent=RealExponent+1023bias”(偏差:2^(11-1)-1= 1023),指数(11位)是6+1023=1029。

代码语言:javascript
复制
from10to2(1029) # ("10000000101")2

双精度存储:

10000000101 10000000101\ 010110001000 (但这不是64位,而是1+11+12=24位!)

符号,符号,指数,指数,意义。真正的64位双精度必须是:

10000000101 - 0101100010000000000000000000000000000000000000000000.

因此,这种方法不能找到最后的40个零,但可以正确地找到前24位。

在线转换器:

  1. https://www.exploringbinary.com/floating-point-converter/ 生源二进制(符号域、符号域、指数域、意义域和域)双:
  2. double.html

我的技术(适用于0.3和-2.94)意外地停止了86.125的工作,并且没有产生64位。

为什么这项技术在86.125年会停止呢?

是否已经有一种方法可以转换:

  • (十进制)内存中标准化双精度的数值
  • 内存中的标准化双精度为(十进制)数值?

(我希望我所做的不是从头开始重新发现美国)

任何帮助都是非常感谢的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-05-25 19:56:37

代码语言:javascript
复制
library(BMS)

from10toNdp <- function(my10baseNumber) {
out <- list()

# Handle special cases (0, Inf, -Inf)
if (my10baseNumber %in% c(0,Inf,-Inf)) {
if (my10baseNumber==0)    { out <- "0000000000000000000000000000000000000000000000000000000000000000" }
if (my10baseNumber==Inf)  { out <- "0111111111110000000000000000000000000000000000000000000000000000" }
if (my10baseNumber==-Inf) { out <- "1111111111110000000000000000000000000000000000000000000000000000" }
} else {

signBit <- 0 # assign initial value

from10to2 <- function(deciNumber) {
  binaryVector <- rep(0, 1 + floor(log(deciNumber, 2)))
  while (deciNumber >= 2) {
    theExpo <- floor(log(deciNumber, 2))
    binaryVector[1 + theExpo] <- 1
    deciNumber <- deciNumber - 2^theExpo  }
  binaryVector[1] <- deciNumber %% 2
  paste(rev(binaryVector), collapse = "")}

#Sign bit
if (my10baseNumber<0) { signBit <- 1 
} else { signBit <- 0 }

# Biased Exponent
BiasedExponent <- strsplit(from10to2(as.numeric(substr(sprintf("%a", my10baseNumber), which(strsplit( sprintf("%a", my10baseNumber), "")[[1]]=="p")+1, length( strsplit( sprintf("%a", my10baseNumber), "")[[1]]))) + 1023), "")[[1]] 
BiasedExponent <- paste(BiasedExponent, collapse='')
if (nchar(BiasedExponent)<11) {BiasedExponent <-  paste(c(  rep(0,11-nchar(BiasedExponent)), BiasedExponent),collapse='')    }

# Significand
significand <- BMS::hex2bin(substr( sprintf("%a", my10baseNumber) , which(strsplit( sprintf("%a", my10baseNumber), "")[[1]]=="x")+3, which(strsplit( sprintf("%a", my10baseNumber), "")[[1]]=="p")-1))

significand <- paste(significand, collapse='')
if (nchar(significand)<52) {significand <-  paste(c( significand,rep(0,52-nchar(significand))),collapse='')    }

out <- paste(c(signBit, BiasedExponent, significand), collapse='')
}

out
}


from10toNdp(0.3)
# "0011111111010011001100110011001100110011001100110011001100110011"
from10toNdp(-2.94)
# "1100000000000111100001010001111010111000010100011110101110000101"
from10toNdp(86.125)
# "0100000001010101100010000000000000000000000000000000000000000000"
from10toNdp(-589546.684259)
# "1100000100100001111111011101010101011110010101110011001000010110"

from10toNdp(0)
# "0000000000000000000000000000000000000000000000000000000000000000"
from10toNdp(Inf)
# "0111111111110000000000000000000000000000000000000000000000000000"
from10toNdp(-Inf)
# "1111111111110000000000000000000000000000000000000000000000000000"
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56289012

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档