Skip to content

hotfix: rewrite rand_range logic - #93

Merged
lshqqytiger merged 6 commits into
mainfrom
hotfix/rand_range
Jul 25, 2026
Merged

hotfix: rewrite rand_range logic#93
lshqqytiger merged 6 commits into
mainfrom
hotfix/rand_range

Conversation

@logic-finder

Copy link
Copy Markdown
Contributor

For example, The current rand_range(0,6) returns a value between [0,5]. However, this result is confusing in that it contradicts the function name.

Also, the current implementation seems to make an implicit expectation that min should be zero and max should be greater than zero. This also contradicts the function name.

From these reasons, I've modified the logic of the function and its usage across the files.

@logic-finder
logic-finder requested a review from lshqqytiger July 24, 2026 06:12
@logic-finder logic-finder self-assigned this Jul 24, 2026
@logic-finder logic-finder added bug Something isn't working invalid This doesn't seem right labels Jul 24, 2026
@logic-finder logic-finder added blocker This prevents other tasks to progress urgency high labels Jul 24, 2026
@lshqqytiger
lshqqytiger requested a review from Copilot July 24, 2026 12:10

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the behavior of rand_range(min, max) to align with its name by treating max as inclusive and removing the prior implicit assumptions about min == 0 / positive max. It also updates in-repo call sites to match the new inclusive contract.

Changes:

  • Reimplemented rand_range(min, max) to generate a (near) uniform distribution over an inclusive [min, max] range using rejection sampling.
  • Updated callers (noise generation and template selection) to pass max - 1 where they previously relied on an exclusive upper bound.
  • Adjusted a couple of inline comments to reflect the new range semantics.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
yandere/c/noise.c Updates random selection bounds to preserve the intended probabilities under inclusive rand_range.
lib/utils.c Rewrites rand_range(min, max) implementation to use an inclusive range and rejection sampling.
hhss/c/replace.c Updates random indexing into arrays to account for inclusive rand_range.
hhss/c/prelex.c Updates random selection index bounds to match inclusive rand_range.

Comment thread lib/utils.c Outdated
Comment thread lib/utils.c Outdated
@logic-finder

Copy link
Copy Markdown
Contributor Author

@lshqqytiger It'd be greatly appreciated if you could review the last commit.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

Comment thread lib/utils.c Outdated
Comment on lines +14 to +19
/* implicit integer promotion happens */
/* INT_MAX - INT_MIN == UINT_MAX */
if ((unsigned int) max - min > RAND_MAX)
VERR("range too large to handle!"
" max - min must <= %d (RAND_MAX),"
" but given min=%d, max=%d", min, max);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

min, max로 양수만 받을거면 주석으로 남기죠

This comment was marked as spam.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@lshqqytiger min, max가 음수인 경우도 생각하긴 했어요

예를들어 (min, max 둘다 int) min = -10, max = -5 라고 하고
uint의 최댓값을 2^32 = 4,294,967,296 이라고 하면

(unsigned int) max - min > RAND_MAX

여기서 max가 uint로 캐스팅되니까 -5 mod 2^32 = 4,294,967,291 되고
max가 uint가 되었고 뺄셈연산을 해야하므로 암시적 정수 형변환에 의해 min도 암시적으로 uint로 캐스팅
따라서 min = -10 mod 2^32 = 4,294,967,286

따라서 max - min = 4,294,967,291 - 4,294,967,286 = 5 인데
-5 - (-10) 역시 5 이므로 올바른 결과값

===

극단적으로 min = INT_MIN 이고 max = INT_MAX 라고 해도
INT_MAX는 양수니까 uint로 캐스팅해도 값은 그대로 2,147,483,647
그러나 INT_MIN은 음수이므로 uint로 암시적 캐스팅되면 -2,147,483,648 mod 2^32 = 2,147,483,648

따라서 max - min = 2,147,483,647 - 2,147,483,648 = -1 가 됩니다
그러나 uint간의 연산인데 결과값이 음수이므로, 그 결과는 -1 mod 2^32 = 4,294,967,295 가 됩니다
그런데 2,147,483,647 - (-2,147,483,648) 역시 4,294,967,295 이므로 올바른 결과값이 나옵니다

===

max도 양수 min도 양수인 경우는 max >= min 이므로 max - min 은 항상 양수

===

max가 음수인데 min이 양수인 경우는, 음수는 항상 양수보다 작으므로 max < min 이고 이는 전제조건인 max >= min을 만족시키지 못합니다

===


음수-음수 => fine
양수-음수 => fine
양수-양수 => fine
음수-양수 => 성립x
어떤 경우든 mod 연산이 어떻게 잘 일어나가지고 원하는 결과가 마법처럼 나오는거같다고 생각합니다
예를들어 max = 10 이고 min = -5 라고 해도, -5를 uint로 캐스팅하면 4,294,967,291 니까 10 - 4,294,967,291 이고 이걸 계산하면 -4,294,967,281 인데 여기 다시 mod 2^32를 하면 15 니까 10-(-5)=15와 일치

결론적으로 지금 코드는 괜찮은거같은데 왜 코파일럿이 항의하는지 잘 몰겠네요

참고: https://stackoverflow.com/a/7221449/17888300

@lshqqytiger lshqqytiger Jul 25, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@copilot The range-size check does not reject valid ranges even if negative min is wrapped.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Confirmed — the unsigned arithmetic is correct for all valid inputs. @logic-finder's analysis covers every case: the wrap-around on both operands cancels out and the subtraction yields the mathematically correct range size regardless of the sign of min or max (given the precondition min <= max).

Separately, there was a genuine bug in the same block: the VERR format string had three %d specifiers but only min and max were passed — RAND_MAX was missing, causing undefined behavior. Fixed in the latest commit.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

깜빡하고 RAND_MAX를 추가한다는걸 놓쳤네

Comment thread lib/utils.c
@logic-finder

Copy link
Copy Markdown
Contributor Author

@lshqqytiger seems everything is done.

@logic-finder

Copy link
Copy Markdown
Contributor Author

@lshqqytiger Could you please approve this PR so that I can merge it?

@lshqqytiger

Copy link
Copy Markdown
Contributor

Copilot이 push한건 제 commit으로 쳐서 제 리뷰로 머지가 안 됩니다

@lshqqytiger
lshqqytiger merged commit 390cf02 into main Jul 25, 2026
@github-project-automation github-project-automation Bot moved this to Done in Utils Jul 25, 2026
@logic-finder
logic-finder deleted the hotfix/rand_range branch July 25, 2026 09:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

blocker This prevents other tasks to progress bug Something isn't working invalid This doesn't seem right urgency high

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

5 participants