Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 6590888

Browse files
committedMar 19, 2025
Auto merge of #137357 - syvb:sv/log-docs, r=<try>
Document results of non-positive logarithms The integer versions of logarithm functions panic on non-positive numbers. The floating point versions have different, undocumented behaviour (-inf on 0, NaN on <0). This PR documents that. try-job: aarch64-gnu
2 parents 1aeb99d + ecdfd07 commit 6590888

File tree

4 files changed

+190
-0
lines changed

4 files changed

+190
-0
lines changed
 

‎library/std/src/f128.rs

+55
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,8 @@ impl f128 {
468468

469469
/// Returns the natural logarithm of the number.
470470
///
471+
/// This returns NaN when the number is negative, and negative infinity when number is zero.
472+
///
471473
/// # Unspecified precision
472474
///
473475
/// The precision of this function is non-deterministic. This means it varies by platform,
@@ -489,6 +491,15 @@ impl f128 {
489491
/// assert!(abs_difference <= f128::EPSILON);
490492
/// # }
491493
/// ```
494+
///
495+
/// Non-positive values:
496+
/// ```
497+
/// #![feature(f128)]
498+
/// # #[cfg(reliable_f128_math)] {
499+
/// assert_eq!(0_f128.ln(), f128::NEG_INFINITY);
500+
/// assert!((-42_f128).ln().is_nan());
501+
/// # }
502+
/// ```
492503
#[inline]
493504
#[rustc_allow_incoherent_impl]
494505
#[unstable(feature = "f128", issue = "116909")]
@@ -499,6 +510,8 @@ impl f128 {
499510

500511
/// Returns the logarithm of the number with respect to an arbitrary base.
501512
///
513+
/// This returns NaN when the number is negative, and negative infinity when number is zero.
514+
///
502515
/// The result might not be correctly rounded owing to implementation details;
503516
/// `self.log2()` can produce more accurate results for base 2, and
504517
/// `self.log10()` can produce more accurate results for base 10.
@@ -522,6 +535,15 @@ impl f128 {
522535
/// assert!(abs_difference <= f128::EPSILON);
523536
/// # }
524537
/// ```
538+
///
539+
/// Non-positive values:
540+
/// ```
541+
/// #![feature(f128)]
542+
/// # #[cfg(reliable_f128_math)] {
543+
/// assert_eq!(0_f128.log(10.0), f128::NEG_INFINITY);
544+
/// assert!((-42_f128).log(10.0).is_nan());
545+
/// # }
546+
/// ```
525547
#[inline]
526548
#[rustc_allow_incoherent_impl]
527549
#[unstable(feature = "f128", issue = "116909")]
@@ -532,6 +554,8 @@ impl f128 {
532554

533555
/// Returns the base 2 logarithm of the number.
534556
///
557+
/// This returns NaN when the number is negative, and negative infinity when number is zero.
558+
///
535559
/// # Unspecified precision
536560
///
537561
/// The precision of this function is non-deterministic. This means it varies by platform,
@@ -551,6 +575,15 @@ impl f128 {
551575
/// assert!(abs_difference <= f128::EPSILON);
552576
/// # }
553577
/// ```
578+
///
579+
/// Non-positive values:
580+
/// ```
581+
/// #![feature(f128)]
582+
/// # #[cfg(reliable_f128_math)] {
583+
/// assert_eq!(0_f128.log2(), f128::NEG_INFINITY);
584+
/// assert!((-42_f128).log2().is_nan());
585+
/// # }
586+
/// ```
554587
#[inline]
555588
#[rustc_allow_incoherent_impl]
556589
#[unstable(feature = "f128", issue = "116909")]
@@ -561,6 +594,8 @@ impl f128 {
561594

562595
/// Returns the base 10 logarithm of the number.
563596
///
597+
/// This returns NaN when the number is negative, and negative infinity when number is zero.
598+
///
564599
/// # Unspecified precision
565600
///
566601
/// The precision of this function is non-deterministic. This means it varies by platform,
@@ -580,6 +615,15 @@ impl f128 {
580615
/// assert!(abs_difference <= f128::EPSILON);
581616
/// # }
582617
/// ```
618+
///
619+
/// Non-positive values:
620+
/// ```
621+
/// #![feature(f128)]
622+
/// # #[cfg(reliable_f128_math)] {
623+
/// assert_eq!(0_f128.log10(), f128::NEG_INFINITY);
624+
/// assert!((-42_f128).log10().is_nan());
625+
/// # }
626+
/// ```
583627
#[inline]
584628
#[rustc_allow_incoherent_impl]
585629
#[unstable(feature = "f128", issue = "116909")]
@@ -966,6 +1010,8 @@ impl f128 {
9661010
/// Returns `ln(1+n)` (natural logarithm) more accurately than if
9671011
/// the operations were performed separately.
9681012
///
1013+
/// This returns NaN when `n < -1.0`, and negative infinity when `n == -1.0`.
1014+
///
9691015
/// # Unspecified precision
9701016
///
9711017
/// The precision of this function is non-deterministic. This means it varies by platform,
@@ -989,6 +1035,15 @@ impl f128 {
9891035
/// assert!(abs_difference < 1e-10);
9901036
/// # }
9911037
/// ```
1038+
///
1039+
/// Out-of-range values:
1040+
/// ```
1041+
/// #![feature(f128)]
1042+
/// # #[cfg(reliable_f128_math)] {
1043+
/// assert_eq!((-1.0_f128).ln_1p(), f128::NEG_INFINITY);
1044+
/// assert!((-2.0_f128).ln_1p().is_nan());
1045+
/// # }
1046+
/// ```
9921047
#[inline]
9931048
#[doc(alias = "log1p")]
9941049
#[must_use = "method returns a new number and does not mutate the original value"]

‎library/std/src/f16.rs

+55
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,8 @@ impl f16 {
468468

469469
/// Returns the natural logarithm of the number.
470470
///
471+
/// This returns NaN when the number is negative, and negative infinity when number is zero.
472+
///
471473
/// # Unspecified precision
472474
///
473475
/// The precision of this function is non-deterministic. This means it varies by platform,
@@ -489,6 +491,15 @@ impl f16 {
489491
/// assert!(abs_difference <= f16::EPSILON);
490492
/// # }
491493
/// ```
494+
///
495+
/// Non-positive values:
496+
/// ```
497+
/// #![feature(f16)]
498+
/// # #[cfg(reliable_f16_math)] {
499+
/// assert_eq!(0_f16.ln(), f16::NEG_INFINITY);
500+
/// assert!((-42_f16).ln().is_nan());
501+
/// # }
502+
/// ```
492503
#[inline]
493504
#[rustc_allow_incoherent_impl]
494505
#[unstable(feature = "f16", issue = "116909")]
@@ -499,6 +510,8 @@ impl f16 {
499510

500511
/// Returns the logarithm of the number with respect to an arbitrary base.
501512
///
513+
/// This returns NaN when the number is negative, and negative infinity when number is zero.
514+
///
502515
/// The result might not be correctly rounded owing to implementation details;
503516
/// `self.log2()` can produce more accurate results for base 2, and
504517
/// `self.log10()` can produce more accurate results for base 10.
@@ -522,6 +535,15 @@ impl f16 {
522535
/// assert!(abs_difference <= f16::EPSILON);
523536
/// # }
524537
/// ```
538+
///
539+
/// Non-positive values:
540+
/// ```
541+
/// #![feature(f16)]
542+
/// # #[cfg(reliable_f16_math)] {
543+
/// assert_eq!(0_f16.log(10.0), f16::NEG_INFINITY);
544+
/// assert!((-42_f16).log(10.0).is_nan());
545+
/// # }
546+
/// ```
525547
#[inline]
526548
#[rustc_allow_incoherent_impl]
527549
#[unstable(feature = "f16", issue = "116909")]
@@ -532,6 +554,8 @@ impl f16 {
532554

533555
/// Returns the base 2 logarithm of the number.
534556
///
557+
/// This returns NaN when the number is negative, and negative infinity when number is zero.
558+
///
535559
/// # Unspecified precision
536560
///
537561
/// The precision of this function is non-deterministic. This means it varies by platform,
@@ -551,6 +575,15 @@ impl f16 {
551575
/// assert!(abs_difference <= f16::EPSILON);
552576
/// # }
553577
/// ```
578+
///
579+
/// Non-positive values:
580+
/// ```
581+
/// #![feature(f16)]
582+
/// # #[cfg(reliable_f16_math)] {
583+
/// assert_eq!(0_f16.log2(), f16::NEG_INFINITY);
584+
/// assert!((-42_f16).log2().is_nan());
585+
/// # }
586+
/// ```
554587
#[inline]
555588
#[rustc_allow_incoherent_impl]
556589
#[unstable(feature = "f16", issue = "116909")]
@@ -561,6 +594,8 @@ impl f16 {
561594

562595
/// Returns the base 10 logarithm of the number.
563596
///
597+
/// This returns NaN when the number is negative, and negative infinity when number is zero.
598+
///
564599
/// # Unspecified precision
565600
///
566601
/// The precision of this function is non-deterministic. This means it varies by platform,
@@ -580,6 +615,15 @@ impl f16 {
580615
/// assert!(abs_difference <= f16::EPSILON);
581616
/// # }
582617
/// ```
618+
///
619+
/// Non-positive values:
620+
/// ```
621+
/// #![feature(f16)]
622+
/// # #[cfg(reliable_f16_math)] {
623+
/// assert_eq!(0_f16.log10(), f16::NEG_INFINITY);
624+
/// assert!((-42_f16).log10().is_nan());
625+
/// # }
626+
/// ```
583627
#[inline]
584628
#[rustc_allow_incoherent_impl]
585629
#[unstable(feature = "f16", issue = "116909")]
@@ -964,6 +1008,8 @@ impl f16 {
9641008
/// Returns `ln(1+n)` (natural logarithm) more accurately than if
9651009
/// the operations were performed separately.
9661010
///
1011+
/// This returns NaN when `n < -1.0`, and negative infinity when `n == -1.0`.
1012+
///
9671013
/// # Unspecified precision
9681014
///
9691015
/// The precision of this function is non-deterministic. This means it varies by platform,
@@ -987,6 +1033,15 @@ impl f16 {
9871033
/// assert!(abs_difference < 1e-4);
9881034
/// # }
9891035
/// ```
1036+
///
1037+
/// Out-of-range values:
1038+
/// ```
1039+
/// #![feature(f16)]
1040+
/// # #[cfg(reliable_f16_math)] {
1041+
/// assert_eq!((-1.0_f16).ln_1p(), f16::NEG_INFINITY);
1042+
/// assert!((-2.0_f16).ln_1p().is_nan());
1043+
/// # }
1044+
/// ```
9901045
#[inline]
9911046
#[doc(alias = "log1p")]
9921047
#[rustc_allow_incoherent_impl]

‎library/std/src/f32.rs

+40
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,8 @@ impl f32 {
424424

425425
/// Returns the natural logarithm of the number.
426426
///
427+
/// This returns NaN when the number is negative, and negative infinity when number is zero.
428+
///
427429
/// # Unspecified precision
428430
///
429431
/// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
@@ -441,6 +443,12 @@ impl f32 {
441443
///
442444
/// assert!(abs_difference <= f32::EPSILON);
443445
/// ```
446+
///
447+
/// Non-positive values:
448+
/// ```
449+
/// assert_eq!(0_f32.ln(), f32::NEG_INFINITY);
450+
/// assert!((-42_f32).ln().is_nan());
451+
/// ```
444452
#[rustc_allow_incoherent_impl]
445453
#[must_use = "method returns a new number and does not mutate the original value"]
446454
#[stable(feature = "rust1", since = "1.0.0")]
@@ -451,6 +459,8 @@ impl f32 {
451459

452460
/// Returns the logarithm of the number with respect to an arbitrary base.
453461
///
462+
/// This returns NaN when the number is negative, and negative infinity when number is zero.
463+
///
454464
/// The result might not be correctly rounded owing to implementation details;
455465
/// `self.log2()` can produce more accurate results for base 2, and
456466
/// `self.log10()` can produce more accurate results for base 10.
@@ -470,6 +480,12 @@ impl f32 {
470480
///
471481
/// assert!(abs_difference <= f32::EPSILON);
472482
/// ```
483+
///
484+
/// Non-positive values:
485+
/// ```
486+
/// assert_eq!(0_f32.log(10.0), f32::NEG_INFINITY);
487+
/// assert!((-42_f32).log(10.0).is_nan());
488+
/// ```
473489
#[rustc_allow_incoherent_impl]
474490
#[must_use = "method returns a new number and does not mutate the original value"]
475491
#[stable(feature = "rust1", since = "1.0.0")]
@@ -480,6 +496,8 @@ impl f32 {
480496

481497
/// Returns the base 2 logarithm of the number.
482498
///
499+
/// This returns NaN when the number is negative, and negative infinity when number is zero.
500+
///
483501
/// # Unspecified precision
484502
///
485503
/// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
@@ -495,6 +513,12 @@ impl f32 {
495513
///
496514
/// assert!(abs_difference <= f32::EPSILON);
497515
/// ```
516+
///
517+
/// Non-positive values:
518+
/// ```
519+
/// assert_eq!(0_f32.log2(), f32::NEG_INFINITY);
520+
/// assert!((-42_f32).log2().is_nan());
521+
/// ```
498522
#[rustc_allow_incoherent_impl]
499523
#[must_use = "method returns a new number and does not mutate the original value"]
500524
#[stable(feature = "rust1", since = "1.0.0")]
@@ -505,6 +529,8 @@ impl f32 {
505529

506530
/// Returns the base 10 logarithm of the number.
507531
///
532+
/// This returns NaN when the number is negative, and negative infinity when number is zero.
533+
///
508534
/// # Unspecified precision
509535
///
510536
/// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
@@ -520,6 +546,12 @@ impl f32 {
520546
///
521547
/// assert!(abs_difference <= f32::EPSILON);
522548
/// ```
549+
///
550+
/// Non-positive values:
551+
/// ```
552+
/// assert_eq!(0_f32.log10(), f32::NEG_INFINITY);
553+
/// assert!((-42_f32).log10().is_nan());
554+
/// ```
523555
#[rustc_allow_incoherent_impl]
524556
#[must_use = "method returns a new number and does not mutate the original value"]
525557
#[stable(feature = "rust1", since = "1.0.0")]
@@ -893,6 +925,8 @@ impl f32 {
893925
/// Returns `ln(1+n)` (natural logarithm) more accurately than if
894926
/// the operations were performed separately.
895927
///
928+
/// This returns NaN when `n < -1.0`, and negative infinity when `n == -1.0`.
929+
///
896930
/// # Unspecified precision
897931
///
898932
/// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
@@ -911,6 +945,12 @@ impl f32 {
911945
///
912946
/// assert!(abs_difference < 1e-10);
913947
/// ```
948+
///
949+
/// Out-of-range values:
950+
/// ```
951+
/// assert_eq!((-1.0_f32).ln_1p(), f32::NEG_INFINITY);
952+
/// assert!((-2.0_f32).ln_1p().is_nan());
953+
/// ```
914954
#[doc(alias = "log1p")]
915955
#[rustc_allow_incoherent_impl]
916956
#[must_use = "method returns a new number and does not mutate the original value"]
There was a problem loading the remainder of the diff.

0 commit comments

Comments
 (0)
Failed to load comments.