1

I am implementing conversion from RGB to Yxy color and the pseudocode guides me to execute XOR (^) operation on two float variables. How I can do this in python? I get this error:

unsupported operand type(s) for ^: 'float' and 'float'

Take a look at this pseudocode: http://www.easyrgb.com/index.php?X=MATH&H=02#text2.

Abhijit
  • 62,056
  • 18
  • 131
  • 204
lkawon
  • 49
  • 1
  • 5

3 Answers3

4

There is no inbuilt support for xoring floating point numbers. Instead you have to implement one using the struct module

>>> from struct import pack, unpack
>>> def xor_float(f1, f2):
    f1 = int(''.join(hex(ord(e))[2:] for e in struct.pack('d',f1)),16)
    f2 = int(''.join(hex(ord(e))[2:] for e in struct.pack('d',f2)),16)
    xor = f1 ^ f2
    xor = "{:016x}".format(xor)
    xor = ''.join(chr(int(xor[i:i+2],16)) for i in range(0,len(xor),2))
    return struct.unpack('d',xor)[0]

>>> xor_float(10.25,10.25)
0.0
>>> xor_float(10.25,0.00)
10.25

Note This example assumes, that the floating point number is a 64 bit float, as natively supported by Python


I should have seen your pseudo-code before jumping in to solving this problem. The caret ^ in the pseudo-code is power rather than xor and in python raising a number to power (including float) is done through ** or math.pow

Abhijit
  • 62,056
  • 18
  • 131
  • 204
0

You can only apply bit wise operators to integers. So convert the floats to integer first.

Peter Wooster
  • 6,009
  • 2
  • 27
  • 39
  • This will result in loosing information (and having a wrong result from XOR) because the int() cast on a float is always the integer part – Samuele Mattiuzzo Jan 22 '13 at 14:42
  • @SamueleMattiuzzo if that's the point, just use `round(number, digits)` – whatyouhide Jan 22 '13 at 14:46
  • @whatyouhide and that's where you will get another float, not suitable for a XOR again – Samuele Mattiuzzo Jan 22 '13 at 14:48
  • 1
    If you work on RGB images, the values are usually, for each channel, 0..255, but some libraries present them as 0.0...1.0. Maybe conversion to int via `int_value = int(round(255*float_value))` – Thorsten Kranz Jan 22 '13 at 15:01
  • @SamueleMattiuzzo `int(round(number))` will round to the next integer. – whatyouhide Jan 22 '13 at 15:01
  • @whatyouhide still there is information loss. not suitable for the op (on RGB, 2.55 is different than 2.20). Also, int(3.4) and int(round(3.4, )) both yeld (as expected) 3. Still not correct :) – Samuele Mattiuzzo Jan 22 '13 at 15:03
  • @SamueleMattiuzzo I didn't say to cast it to integer, I said to convert it, that implies using whatever means is needed to make a whole number. I know that cast will lose the fraction as will floor or round. e.g. thorstenkranz's comment – Peter Wooster Jan 22 '13 at 15:27
  • @SamueleMattiuzzo obviously you'll lose information, I wasn't suggesting a solution to your problem, just saying that there are ways to avoid and integer cast. :) – whatyouhide Jan 22 '13 at 16:26
  • I do have no problems at all, especially with floats and ints :P – Samuele Mattiuzzo Jan 22 '13 at 16:27
0
import struct, math

def fxor(a, b):
  rtrn = []
  a = struct.pack('d', a)
  b = struct.pack('d', b)
  for ba, bb in zip(a, b):
    rtrn.append(ba ^ bb)

  return struct.unpack('d', bytes(rtrn))[0]

print(fxor(math.pi, math.pi)) #0.0
print(fxor(math.e, math.pi))  #1.7551491316820714e-308
print(fxor(math.pi, 0))       #3.141592653589793

64-bit float xor. This performs an xor operation on each bit that makes up the floating point and returns it as a double and/or 64-bit float

CoderBoy
  • 107
  • 11
  • I don't know if this still helps anyone but there are reasons to xor floats and this is a pretty straightforward way. However, in pseudocode, `^` does mean exponent. Not every language revolves around python... – CoderBoy Aug 20 '18 at 23:03