Skip to content

Conversation

@toseko
Copy link
Contributor

@toseko toseko commented Oct 13, 2025

No description provided.

@toseko toseko requested a review from killenb October 13, 2025 07:11
if(_isSigned) {
return toRaw(std::stoi(cookedValue));
}
return toRaw(static_cast<uint32_t>(std::stoul(cookedValue))); // on some compilers, long might be a
Copy link
Member

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.

Copy link
Contributor Author

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?

boost::fusion::for_each(_minCookedValues, initCoefficients(this));
}

using DEPRECATED_FIXEDPOINT_DEFAULT = int64_t;
Copy link
Member

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

Copy link
Contributor Author

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.

Copy link
Member

@killenb killenb left a 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]);
Copy link
Member

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]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dito

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
Copy link
Member

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.

Comment on lines 349 to 350
// different type than int...
//
Copy link
Member

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));
Copy link
Member

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) {
Copy link
Member

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.

Copy link
Contributor Author

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.

Comment on lines 412 to 414
catch(boost::numeric::negative_overflow& e) {
raw = _minRawValue;
}
Copy link
Member

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

// some sanity checks
if(nBits > 32) {
// some sanity checks
const auto maxBitsNo = (sizeof(RawType) * 8);
Copy link
Member

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 ;-)

Copy link
Contributor Author

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.

@toseko toseko force-pushed the feat/tkozak-allow-different-rawdata-types branch from a6c8cbf to c566c84 Compare November 6, 2025 16:30
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)));
Copy link
Member

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) {
Copy link
Member

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.

  1. commit: Formally introduce RawType as template parameter, but have an assertion in the constructor that only allows int32_t as type.
  2. 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.

Comment on lines +316 to +319
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)));
Copy link
Member

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))
Copy link
Member

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 ?

Comment on lines 936 to 937
checkToCooked(converter, 0x40000000, 0.25);
checkToCooked(converter, 0xC0000000, -0.25);
Copy link
Member

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants