-
Notifications
You must be signed in to change notification settings - Fork 11
feat: Allow different RawData types #526
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
include/FixedPointConverter.h
Outdated
| if(_isSigned) { | ||
| return toRaw(std::stoi(cookedValue)); | ||
| } | ||
| return toRaw(static_cast<uint32_t>(std::stoul(cookedValue))); // on some compilers, long might be a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one has to static cast to RawType. No, wait. This cast makes no sense at all.
I think this code is broken. Needs further discussion what it does and why. What it does definitely do wong: Input string "12.7" should result in a raw value of 13. And negative numbers also don't work. I have no good implementation right now.
Possible changes for now: Use RawType or don't cast at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think is should not be cast at all. I think casting was done due to fact that initially the raw type was uint32_t, but it still does not make sense as toRaw takes UserType.
Moreover, I wanted whether this casting was doing anything. It is recursive call to method toRaw(UserType) so it always cast to UserType ? or the UserType is not defined explicitly and then this automatic template type detection kicks in and type of parameter is used?
include/FixedPointConverter.h
Outdated
| boost::fusion::for_each(_minCookedValues, initCoefficients(this)); | ||
| } | ||
|
|
||
| using DEPRECATED_FIXEDPOINT_DEFAULT = int64_t; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nopw, that would be int32_t
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, of course you are right. To keep stuff as they are 32bit should be used.
killenb
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe we should make a static assert for the moment that the FixedPointConverter is only instantiated with int32_t?
Apart from that I think we are ready to merge to the master. I would do a full final review af the remaining issues are fixed (only did the delta of the comments and the commit, and lost the overview)
| // For proper implementation of this, the fixed point converter needs to signalize | ||
| // that it had clamped. See https://redmine.msktools.desy.de/issues/12912 | ||
| auto raw = fixedPointConverter.toRaw(buffer_2D[0][0]); | ||
| auto raw = (uint32_t)fixedPointConverter.toRaw(buffer_2D[0][0]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Coding style: Don't use C-style casts.
| } | ||
|
|
||
| auto value = fixedPointConverter.toRaw(buffer_2D[0][0]); | ||
| auto value = (uint32_t)fixedPointConverter.toRaw(buffer_2D[0][0]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dito
include/FixedPointConverter.h
Outdated
| RawType FixedPointConverter<RawType>::toRaw(UserType cookedValue) const { | ||
| if constexpr(std::is_same<UserType, std::string>::value) { | ||
| if(_fractionalBits == 0) { // use integer conversion | ||
| // use integer conversion |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Putting the comment above the if-statement makes is less precise. It belongs into the positive if branch.
include/FixedPointConverter.h
Outdated
| // different type than int... | ||
| // |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By not having the comment behind the code that it affects makes it less clear where it belong.
| // on some compilers, long might be a | ||
| // different type than int... | ||
| // | ||
| return toRaw(std::stoul(cookedValue)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, the comment refers to the cast that you removed. The comment is now wrong, and the code not robust any more to compilers where stoul does not return the RawType
| using converter_signed = boost::numeric::converter<int32_t, double, | ||
| boost::numeric::conversion_traits<int32_t, double>, boost::numeric::def_overflow_handler, Round<double>>; | ||
| raw = converter_signed::convert(d_cooked); | ||
| if constexpr(sizeof(RawType) == 4) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like the if/then/else here any more. There are too may possibilities. Especially, this does not cover 8 bit and 16 bit. We can leave it for now as an "extension" for 64 bits, but we need something better in the long run.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it becames compicated. In general adjusting to 64 bits is also complex. The FixpointConverter implementation uses heavily boost::numeric::converter. All converting from raw to coocked is also based on it. And to do it right we need to distinquish between widths of raw data. Different stuff in needed for 16, 32 and 64 bits.
| catch(boost::numeric::negative_overflow& e) { | ||
| raw = _minRawValue; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For this step we leave the conversion block as it is now. It is sufficient for 32 and 64 bit conversion. We will do the improvement in ticket #13011.
What we need here now is the additional catch block for boost::numeric::positive_overflow
include/FixedPointConverter.h
Outdated
| // some sanity checks | ||
| if(nBits > 32) { | ||
| // some sanity checks | ||
| const auto maxBitsNo = (sizeof(RawType) * 8); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
coding style: Variable name should just be "maxBits".
No is the opposite of Yes ;-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep. Probably its not correct, but I used is as abbreviation from Number - No . It's rather for enumeration so ordering, not for couting the amount of bits.
a6c8cbf to
c566c84
Compare
| fpc.padUnusedBits(rawValue); | ||
| return numericToUserType<UserType>(*(reinterpret_cast<uint32_t*>(&rawValue))); | ||
| if constexpr(sizeof(RawType) == 4) { | ||
| return numericToUserType<UserType>(*(std::bit_cast<uint32_t*>(&rawValue))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std::bit_cast works on an object, not on a pointer (in contrast to the reinterpret_cast), at least according to the docu. I don't know if this does the right thing. Probably it does, because it changes one pointer type into another.
At least it's unnecessarily complicated.
numericToUserType<UserType>(std::bit_cast<uint32_t>(rawValue));
should do the trick.
| if constexpr(sizeof(RawType) == 4) { | ||
| return numericToUserType<UserType>(*(std::bit_cast<uint32_t*>(&rawValue))); | ||
| } | ||
| else if constexpr(sizeof(RawType) == 8) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am wondering if we should separate the 64 bit case into another commit.
- commit: Formally introduce RawType as template parameter, but have an assertion in the constructor that only allows int32_t as type.
- commit: Test extension to 64 bits, then make it work.
We first get commit 1. ready and put it into the master before we are messing with too may things.
| return numericToUserType<UserType>(f * *(std::bit_cast<uint32_t*>(&rawValue))); | ||
| } | ||
| else if constexpr(sizeof(RawType) == 8) { | ||
| return numericToUserType<UserType>(f * *(std::bit_cast<uint64_t*>(&rawValue))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These will start giving trouble if we have 64 bit values with more than 48 significant bits and negative fractional bits > -(64-nSignificant). I guess it's not a realistic scenario, but you would want 64 bit integer user type, which can hold the full resolution, but it is converted through double, which can only hold 48 significant bits.\
| #define SIGNED_HEX_TO_DOUBLE(INPUT) static_cast<double>(static_cast<int32_t>(INPUT)) | ||
| #define SIGNED_HEX_TO_INT64(INPUT) static_cast<int64_t>(static_cast<int32_t>(INPUT)) | ||
|
|
||
| #define SIGNED_HEX16_TO_DOUBLE(INPUT) static_cast<double>(static_cast<int16_t>(INPUT)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about SIGNED_HEX64_TOxxx ?
| checkToCooked(converter, 0x40000000, 0.25); | ||
| checkToCooked(converter, 0xC0000000, -0.25); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not have error messages here?
…he same fractional bit as size of the converter
No description provided.