1

我有两个矩阵a = [120.23, 255.23669877,...]b = [125.000083, 800.0101010,...]在 [0, 999] 中有两个数字。我想使用bitxorforab。我不能这样bitxor使用round

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

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

4

2 回答 2

1

“但我不知道点后数字的最大长度......”

双精度浮点中,您有 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)。

于 2013-08-11T15:17:03.763 回答
1

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

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

我的程序中的函数xor将其每个操作数转换为 BigDecimal。它找到一些十进制数字来移动小数点以使两个操作数都成为整数。缩放后,它转换为 BigInteger,执行实际的异或,然后转换回 BigDecimal 以撤消缩放。

The main point of this is for you to look at the results, and see whether they are what you want, and would be useful to you if you could do the same thing in Matlab. Explaining any ways in which the results are not what you want may help clarify your requirements for the Matlab experts.

Here is some test output. The top and bottom rows of each block are in decimal. The middle row is the scaled integer versions of the inputs, in hex.

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

Here is the Java program:

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);
  }
}
于 2013-08-11T23:33:02.250 回答