Skip to content

Issue146 misc fixes - #148

Open
almalkim wants to merge 13 commits into
accellera-official:mainfrom
almalkim:issue146_misc_fixes
Open

Issue146 misc fixes#148
almalkim wants to merge 13 commits into
accellera-official:mainfrom
almalkim:issue146_misc_fixes

Conversation

@almalkim

@almalkim almalkim commented Apr 3, 2026

Copy link
Copy Markdown

Fixes adjust_hod() missing after set/clear/packed_rep/subref, rewrites operator=(double), and corrects to_int64() sign extension.

set(int i) and clear(int i) modified digit[] directly but did not
normalize the top digit afterwards.  Without adjust_hod(), spare bits
in the high-order digit retain stale sign-extension data, causing
to_int()/to_uint() and other accessors to return wrong results.

Fixes ticket_bitref_set_clear.
@almalkim

almalkim commented Apr 3, 2026

Copy link
Copy Markdown
Author

Hi @AndrewGoodrich,
Can you please check this PR?
This is handling multiple issues reported in 146.
Regards.

@almalkim

almalkim commented Apr 3, 2026

Copy link
Copy Markdown
Author

Hi @AndrewGoodrich,
Can you please check this PR fixing multiple issues reported in issue 146.
Regards.

@AndrewGoodrich

Copy link
Copy Markdown
Contributor

These are good changes, thank you. A couple of suggested adjustments:

  1. The call to adjust_hod() is not necessary for bit operations on sc_unsigned values because there is a hidden high order bit in the internal reqpresentation so that the two’s-complement representation cannot be negative. (e.g., a 32-bit unsigned value internally is a 33-bit value so is represented by two sc_digits.
  2. In the code implementing an assignment from a double use a call to vector_twos_complement() rather than explicitly doing the same thing.
  3. In that same assignment code for double, keep the if – else that uses the remainder() function for non-Windows platforms.

almalkim added 7 commits April 4, 2026 22:45
The previous implementation used remainder() which can return negative
values, and omitted adjust_hod() leaving stale sign-extension bits in
the high-order digit.

New implementation:
- truncates toward zero with std::trunc()
- extracts digits using std::fmod/std::floor (always non-negative)
- negates via two's complement for negative inputs
- calls adjust_hod() to normalise the top digit

Fixes ticket_op_assign_double.
Mirrors the same fix applied to sc_signed.  The previous implementation
used remainder() (which can return negative values) and omitted
adjust_hod(), leaving stale bits in the high-order digit.

New implementation:
- truncates toward zero with std::trunc()
- takes absolute value before digit extraction
- extracts digits using std::fmod/std::floor
- calls adjust_hod() to normalise the top digit

Fixes ticket_op_assign_double.
…git[]

get_packed_rep() writes raw sc_digit values from the caller's buffer
into digit[] (the name is misleading — it actually sets, not gets).
Without adjust_hod() the spare bits in the high-order digit are left
un-normalized, so subsequent to_int()/to_uint() calls return stale
values.

Fixes ticket_packed_rep.
…(double)

Two fixes in sc_unsigned.cpp:

1. set_packed_rep(): after writing bits from the caller's buffer into
   digit[], the high-order digit was not normalized.  Added adjust_hod()
   so that spare bits above position (W-1) are always zeroed.
   Fixes ticket_packed_rep.

2. sc_unsigned_subref::operator=(double): rewrote digit extraction to
   use std::trunc/std::fmod/std::floor (same pattern as the signed fix)
   and added m_obj_p->adjust_hod() after vector_insert_bits() so the
   parent object's top digit is normalized.
   Fixes ticket_subref_assign_double.
@almalkim
almalkim force-pushed the issue146_misc_fixes branch from df61437 to b645d9a Compare April 4, 2026 20:18
almalkim added 3 commits April 4, 2026 23:40
to_int64(): for 33 <= W < 64 the two-digit assembly produced a positive
value even for negative inputs because the upper word only fills bits
32..(W-1), leaving the sign bit at position (W-1) rather than bit 63.
Added arithmetic sign extension via shift-left/shift-right after assembly.

Fixes ticket_to_int64.
When nbits is between 33 and 63, the two-digit assembly leaves the
result sign bit at position (nbits-1) instead of bit 63. Added
arithmetic sign extension via shift-left/shift-right, mirroring the
same fix applied to sc_bigint<W>::to_int64().

Fixes ticket_to_int64.
@almalkim
almalkim force-pushed the issue146_misc_fixes branch from b645d9a to 5f6b99f Compare April 4, 2026 20:51
@almalkim

almalkim commented Apr 4, 2026

Copy link
Copy Markdown
Author

All fixed

@AndrewGoodrich

Copy link
Copy Markdown
Contributor

The shifts for signs propagation in to_int64() are not necessary because the internal values always contain sign-propagation in the unused upper bits. So an sc_bigint<40> will have its bits 40 through 63 as ones if it is a negative number.

The adjust_hod() invariant guarantees that all bits above the value
width are already sign-extended in the internal two's-complement
representation, so the explicit shift-left/shift-right sign propagation
in sc_bigint::to_int64() and sc_signed::to_int64() is redundant.

Addresses reviewer feedback.
@almalkim

Copy link
Copy Markdown
Author

Hi @AndrewGoodrich,
I wanted to ask if there is anything else that you think needs to be fixed in this change?

Audit against clean upstream confirms only sc_signed bugs:
- sc_signed set()/clear() missing adjust_hod()
- sc_signed operator=(double) floor vs trunc and missing adjust_hod()
- sc_signed get_packed_rep() missing adjust_hod()

Reverts all sc_unsigned.cpp changes (no demonstrated bugs).
Removes to_int64 and subref_assign_double tests (no bugs).
Updates op_assign_double and packed_rep tests to only cover
confirmed sc_signed bugs.
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.

2 participants