双数和bitxor

时间:2013-08-11 13:47:33

标签: matlab floating-point bit-manipulation xor bitwise-xor

我有两个矩阵a = [120.23, 255.23669877,...]b = [125.000083, 800.0101010,...],其中包含[0,999]中的双数字。我想对bitxora使用b。我无法像bitxor这样使用round

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(因为我希望我的结果范围也是[0,999]。但是我不知道小数点后数字的最大长度。k = 16是否支持Matlab中双数的最大范围?bitxor是否支持两个19位数?是否有更好的解?< / p>

2 个答案:

答案 0 :(得分:1)

  

“但我不知道点数后的最大数量......”

double precision floating-point中,您有15-17个有效十进制数字。如果您提供bitxor次双输入,则必须小于intmax('uint64'):1.844674407370955e + 19。最大的双倍realmax(= 1.797693134862316e + 308)比这大得多,所以你不能用你使用的方式表示一切。例如,这意味着您的值800.0101010 * 10 ^ 17将无效。

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

答案 1 :(得分:1)

这不是一个真正的答案,而是对嵌入代码的一个很长的评论。我没有当前的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);
  }
}