Way outside of my experience, as I've only messed about with bitshifts as part of advent of code but the result you get in FME (4278190080) is as you would expect given what you are doing is the following
@Evaluate(255*@pow(2,24))
This is above the max for a 32 bit signed integer (you can see this in the error log in your workspace when you try and convert it using @int32)
Attribute(string) : `fme_expression_warnings{0}.attributeName' has value `shifted_24_as_int32'
Attribute(string) : `fme_expression_warnings{0}.message' has value `Failed to evaluate numeric expression '@int32(4278190080)'. Result is set to null'
Attribute(string) : `fme_expression_warnings{0}.transformerName' has value `AttributeManager'
It looks like postgres is handling the overflow by wrapping around. I don't know how you can recreate this in FME. I know in python 255<<24 will give the result as per FME as the integers in python are not of a fixed bit width, you can use numpy to get the result you are seeing in postgres
import fme
import fmeobjects
import numpy as np
def processFeature(feature):
feature.setAttribute("shifted_24_as_int32",int(np.left_shift(255,24)))
The result you're getting from FME is the correct result for a 64-bit integer (or an unsigned 32-bit integer), also called an arithmetic shift. The result you're getting from Postgres is due to a flipped sign, since the bit shift overflows the signed int32 datatype. This is commonly referred to as a logical shift.
For logical bit manipulations in FME I would recommend using Python, where you can force a specific datatype using the numpy libraries. Example:
>>> import numpy as np
>>> np.int32(255) << 24
-16777216
To help understand the sign bit, consider the above compared to the same bit shift but using an unsigned 32-bit integer:
>>> np.uint32(255) << 24
4278190080
The result you're getting from FME is the correct result for a 64-bit integer (or an unsigned 32-bit integer), also called an arithmetic shift. The result you're getting from Postgres is due to a flipped sign, since the bit shift overflows the signed int32 datatype. This is commonly referred to as a logical shift.
For logical bit manipulations in FME I would recommend using Python, where you can force a specific datatype using the numpy libraries. Example:
>>> import numpy as np
>>> np.int32(255) << 24
-16777216
To help understand the sign bit, consider the above compared to the same bit shift but using an unsigned 32-bit integer:
>>> np.uint32(255) << 24
4278190080
Hi,
Thanks for the reply. After some experimenting with the PythonCaller, I managed to get the desired result.
I have uploaded a new version of my workbench, in case somebody might be interested.
Way outside of my experience, as I've only messed about with bitshifts as part of advent of code but the result you get in FME (4278190080) is as you would expect given what you are doing is the following
@Evaluate(255*@pow(2,24))
This is above the max for a 32 bit signed integer (you can see this in the error log in your workspace when you try and convert it using @int32)
Attribute(string) : `fme_expression_warnings{0}.attributeName' has value `shifted_24_as_int32'
Attribute(string) : `fme_expression_warnings{0}.message' has value `Failed to evaluate numeric expression '@int32(4278190080)'. Result is set to null'
Attribute(string) : `fme_expression_warnings{0}.transformerName' has value `AttributeManager'
It looks like postgres is handling the overflow by wrapping around. I don't know how you can recreate this in FME. I know in python 255<<24 will give the result as per FME as the integers in python are not of a fixed bit width, you can use numpy to get the result you are seeing in postgres
import fme
import fmeobjects
import numpy as np
def processFeature(feature):
feature.setAttribute("shifted_24_as_int32",int(np.left_shift(255,24)))
Thanks. Credits to you too, off course...