Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

nth_root does not restore the rounding mode and can return an upper bound below the true root

Đang mở Phù hợp với người mới
#54 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Đánh giá

Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
68/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
cpp
Lĩnh vực
data

Hướng nghiên cứu

Bắt đầu tại boost/numeric/interval/arith2.hpp ở nth_root và so sánh với fmod, cos và tan trong cùng tệp, các hàm này đã tạo đối tượng làm tròn cho kiểu được bảo vệ. Đọc kết quả đầu ra của chương trình tái hiện: chế độ làm tròn bị thay đổi sau lệnh gọi, và cận trên nhỏ hơn sqrt(x) với một số đầu vào trong (0, 1). Hoàn thành khi hàm khôi phục chế độ làm tròn và các cận chứa căn thực, được kiểm tra bằng chương trình tái hiện và các kiểm thử khoảng hiện có.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

nth_root (in boost/numeric/interval/arith2.hpp) works in the unprotected interval type but never creates a rounding object for the protected type, unlike fmod, cos and tan. This has two effects when it is called from code running in round-to-nearest.

  1. The rounding mode is left changed when the function returns.
  2. For some inputs in (0, 1) the upper bound is below the true root, so the result does not contain it.
Reproducer

Godbolt (GCC trunk, Boost 1.92.0, -std=c++03 -frounding-math)

It calls nth_root(interval<double>(0.80166573794976181), 2) from round-to-nearest, reads the rounding mode before and after, and computes upper^2 - x exactly.

Output (the same on develop at 3957843; nth_root is identical in Boost 1.92.0 and develop):

rounding mode: to nearest before, changed after
nth_root([0.80166573794976181], 2) = [0.89535788260882665, 0.89535788260882687]
upper^2 - x = -1.31841e-17

upper^2 - x is negative, so the upper bound is below sqrt(x).

Tested with

x86-64 Linux, glibc 2.39, double, always with -frounding-math:

  • GCC 13.3: -O0, -O2, -O3, C++03 and C++17, -O2 -mfma, -O2 -mfpmath=387, -m32 -O2
  • Clang 18.1.3: -O0, -O2, -O2 -mfma

All give the result above. It also happens at -O0, so it does not depend on optimization.

How often

I ran 1.6 million pairs (x, k), with x uniform in (0, 1) and k = 2…9, and checked each bound exactly with MPFR. 1,321 upper bounds were below the true root. No lower bound was
wrong. The rounding mode was changed after every call. For x in (1, 1000) no bound was wrong, but the mode was still changed after every call.

No compiler flag changes these counts. Tried on top of -frounding-math:

  • GCC 13.3: -O0, -O2, -ftrapping-math, -fsignaling-nans, -ffloat-store, -fno-inline, -ffp-contract=off, -mfpmath=387, #pragma STDC FENV_ACCESS ON
  • Clang 18.1.3: -O2, -ftrapping-math, -ffp-exception-behavior=strict, -ffp-model=strict (at -O0 and -O2), #pragma STDC FENV_ACCESS ON

With the rounding mode set to upward before the call, or with the caller holding a rounding object (interval<double>::traits_type::rounding rnd;) around the call, there were
no wrong bounds.

Ngôn ngữ chính
C++
Star
31
Fork
48
Merge trung bình
2 ngày 5 phút
Pull request đã merge (30 ngày)
4

Chuẩn bị môi trường

Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của boostorg/interval

Tất cả issue của boostorg/interval

Issue tương tự

Thêm issue về C++

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.