Double numbers and bitxor



我有两个矩阵a = [120.23, 255.23669877,...]b = [125.000083, 800.0101010,...],它们在[0999]中有双数。我想将bitxor用于ab。我不能像这样使用bitxorround

result = bitxor(round(a(1,j),round(b(1,j))

因为小数部分0.23和0.000083,。。。对我来说非常重要。我想也许我可以做a = a*10^kb = b*10^k,并使用bitxor和之后的result/10^k(因为我希望我的结果的范围也为[0999])。但我不知道小数点后数字的最大长度。k = 16支持Matlab中双位数的最大范围吗?bitxor支持两个19位数字吗?有更好的解决方案吗?

这不是一个真正的答案,而是一个非常长的带有嵌入代码的注释。我没有当前的matlab安装,在任何情况下,我都不知道如何在这种情况下回答这个问题。相反,我编写了一个Java程序,我认为它可以满足您的要求。它使用两个Java类,BigInteger和BigDecimal。BigInteger是一种扩展的整数格式。BigDecimal是BigInteger和小数位数的组合。

从double到BigDecimal的转换是精确的。相反方向的转换可能需要舍入。

程序中的函数xor将其每个操作数转换为BigDecimal。它查找小数位数以移动小数点,使两个操作数都为整数。缩放后,它将转换为BigInteger,执行实际的xor,并转换回BigDecimal,从而取消缩放。

这样做的主要目的是让你看看结果,看看它们是否是你想要的,如果你能在Matlab中做同样的事情,这对你会很有用。解释结果不是你想要的任何方式可能有助于澄清你对Matlab专家的要求。

以下是一些测试输出。每个块的顶行和底行都是十进制的。中间一行是输入的缩放整数版本,以十六进制表示。

Testing operands 1.100000000000000088817841970012523233890533447265625, 2
2f0a689f1b94a78f11d31b7ab806d40b1014d3f6d59 xor 558749db77f70029c77506823d22bd0000000000000 = 7a8d21446c63a7a6d6a61df88524690b1014d3f6d59
1.1 xor 2.0 = 2.8657425494106605
Testing operands 100, 200.0004999999999881765688769519329071044921875
2cd76fe086b93ce2f768a00b22a00000000000 xor 59aeee72a26b59f6380fcf078b92c4478e8a13 = 7579819224d26514cf676f0ca932c4478e8a13
100.0 xor 200.0005 = 261.9771865509636
Testing operands 120.3250000000000028421709430404007434844970703125, 120.75
d2c39898113a28d484dd867220659fbb45005915 xor d3822c338b76bab08df9fee485d1b00000000000 = 141b4ab9a4c926409247896a5b42fbb45005915
120.325 xor 120.75 = 0.7174277813579485
Testing operands 120.2300000000000039790393202565610408782958984375, 120.0000830000000036079654819332063198089599609375
d298ff20fbed5fd091d87e56002df79fc7007cb7 xor d231e5f39e1db18654cb8c43d579692616a16a1f = a91ad365f0ee56c513f215d5549eb9d1a116a8
120.23 xor 120.000083 = 0.37711627930683345

这是Java程序:

import java.math.BigDecimal;
import java.math.BigInteger;
public class Test {
  public static double xor(double a, double b) {
    BigDecimal ad = new BigDecimal(a);
    BigDecimal bd = new BigDecimal(b);
    /*
     * Shifting the decimal point right by scale will make both operands
     * integers.
     */
    int scale = Math.max(ad.scale(), bd.scale());
    /*
     * Scale both operands by, in effect, multiplying by the same power of 10.
     */
    BigDecimal aScaled = ad.movePointRight(scale);
    BigDecimal bScaled = bd.movePointRight(scale);
    /*
     * Convert the operands to integers, treating any rounding as an error.
     */
    BigInteger aInt = aScaled.toBigIntegerExact();
    BigInteger bInt = bScaled.toBigIntegerExact();
    BigInteger resultInt = aInt.xor(bInt);
    System.out.println(aInt.toString(16) + " xor " + bInt.toString(16) + " = "
        + resultInt.toString(16));
    /*
     * Undo the decimal point shift, in effect dividing by the same power of 10
     * as was used to scale to integers.
     */
    BigDecimal result = new BigDecimal(resultInt, scale);
    return result.doubleValue();
  }
  public static void test(double a, double b) {
    System.out.println("Testing operands " + new BigDecimal(a) + ", " + new BigDecimal(b));
    double result = xor(a, b);
    System.out.println(a + " xor " + b + " = " + result);
    System.out.println();
  }
  public static void main(String arg[])
  {
    test(1.1, 2.0);
    test(100, 200.0005);
    test(120.325, 120.75);
    test(120.23, 120.000083);
  }
}

"但我不知道点后数字的最大长度…"

在双精度浮点中,您有15–17位有效的十进制数字。如果给bitxor两个输入,这些值必须小于intmax('uint64'):1.844674407370955e+19。最大的double,realmax(=1.797693134862316e+308),比这个大得多,所以你不能用你使用的方式来表示所有的东西。例如,这意味着您的值800.0101010*10^17不起作用。

如果你的范围是[0999],一个选项是求解最大的分数指数k,并使用它:log(double(intmax('uint64'))/999)/log(10)(=16.26635434268810)。

最新更新