1

I have two matrices a = [120.23, 255.23669877,...] and b = [125.000083, 800.0101010,...] with double numbers in [0, 999]. I want to use bitxor for a and b. I can not use bitxor with round like this:

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

Because the decimal parts 0.23 and 0.000083 ,... are very important to me. I thought maybe I could do a = a*10^k and b = b*10^k and use bitxor and after that result/10^k (because I want my result's range to also be [0, 999]. But I do not know the maximum length of the number after the decimal point. Does k = 16 support the max range of double numbers in Matlab? Does bitxor support two 19-digit numbers? Is there a better solution?

horchler
  • 18,384
  • 4
  • 37
  • 73
sa Zas
  • 49
  • 7
  • 3
    What do you want the result of `xor(120.23, 125.000083)` to be? – harold Aug 11 '13 at 16:00
  • 2
    XOR is normally defined only for arrays of bits. It is defined for integers only because integers are a convenient way to manage bits. Normally, the XOR of two integers is not interesting mathematically; it is the underlying bits that are of interest. So, extending XOR to numbers with fractional parts is abnormal and is not commonly defined. If you want assistance with this, you must specify **exactly** what results you want, including what results you want in case we have two floating-point numbers that only approximate decimal numerals. To start, answer harold’s question. – Eric Postpischil Aug 11 '13 at 16:08
  • I want using 'b' and bitxor to convert 'a' to new matrix .but also by using new matrix and 'b' and bitxor I should be able to rebuild 'a' .and for this goal I shuold used a's numbers in correct form :(120.23) – sa Zas Aug 11 '13 at 16:40
  • 1
    @PaulR: I am not sure this is a duplicate. Based on OP’s latest comment, it looks like they either want to XOR the underlying encodings of floating-point numbers or XOR the entire values, including the fraction bits, as if they were binary numerals. Converting to integer as in the proposed duplicate will not accomplish either of those. – Eric Postpischil Aug 11 '13 at 17:45
  • 1
    @saZas: You **must** answer these questions: When 120.325 is XORed with 120.75, what is the result? When the double nearest 120.23 (which contains some rounding error) is XORed with the double nearest 120.000083, what is the result? – Eric Postpischil Aug 11 '13 at 17:47
  • 1
    Note that if you have two `double` values `x` and `y` and you attempt to XOR the binary numerals for these (e.g., 11.001 for 3.125), then it is generally impossible to use the result with one of `x` or `y` to recover the other. This is because often the bits of the significands of `x` and `y` will not completely coincide in value (one will have a higher most-significant-bit than the other and a higher least-significant bit), so the result of the XOR will contain more significant bits than a `double` significand can hold, and the result must be rounded, which loses some bits. – Eric Postpischil Aug 11 '13 at 17:50
  • It may be useful to know the underlying problem that makes @saZas want to XOR doubles. – Patricia Shanahan Aug 11 '13 at 22:55

2 Answers2

1

"But I do not know the max length of number after point ..."

In double precision floating-point you have 15–17 significant decimal digits. If you give bitxor double inputs these must be less than intmax('uint64'): 1.844674407370955e+19. The largest double, realmax (= 1.797693134862316e+308), is much bigger than this, so you can't represent everything in the the way you're using. For example, this means that your value of 800.0101010*10^17 won't work.

If your range is [0, 999], one option is to solve for the largest fractional exponent k and use that: log(double(intmax('uint64'))/999)/log(10) (= 16.266354234268810).

horchler
  • 18,384
  • 4
  • 37
  • 73
  • But the result of using typecast is not between [0,999] and I want in Return Process ,results of using bitxor(result(1,j), b(1,j)) = a – sa Zas Aug 11 '13 at 15:37
1

This is not really an answer, but a very long comment with embedded code. I don't have a current matlab installation, and in any case don't know enough to answer the question in that context. Instead, I've written a Java program that I think may do what you are asking for. It uses two Java classes, BigInteger and BigDecimal. BigInteger is an extended integer format. BigDecimal is the combination of a BigInteger and a decimal scale.

Conversion from double to BigDecimal is exact. Conversion in the opposite direction may require rounding.

The function xor in my program converts each of its operands to BigDecimal. It finds a number of decimal digits to move the decimal point by to make both operands integers. After scaling, it converts to BigInteger, does the actual xor, and converts back to BigDecimal undoing the scaling.

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);
  }
}
Patricia Shanahan
  • 25,849
  • 4
  • 38
  • 75