Skip to content

feat: add math/base/special/trunc2f#10673

Open
Aashrith-Vellampalli wants to merge 1 commit intostdlib-js:developfrom
Aashrith-Vellampalli:feat-trunc2f
Open

feat: add math/base/special/trunc2f#10673
Aashrith-Vellampalli wants to merge 1 commit intostdlib-js:developfrom
Aashrith-Vellampalli:feat-trunc2f

Conversation

@Aashrith-Vellampalli
Copy link

Resolves #649.

Description

What is the purpose of this pull request?

This pull request:

  • This PR adds C and JavaScript implementations of math/base/special/trunc2f, including tests and benchmarks.

Related Issues

Does this pull request have any related issues?

This pull request has the following related issues:

Questions

Any questions for reviewers of this pull request?

No.

Other

Any other information relevant to this pull request? This may include screenshots, references, and/or implementation notes.

No.

Checklist

Please ensure the following tasks are completed before submitting this pull request.

AI Assistance

When authoring the changes proposed in this PR, did you use any kind of AI assistance?

  • Yes
  • No

If you answered "yes" above, how did you use AI assistance?

  • Code generation (e.g., when writing an implementation or fixing a bug)
  • Test/benchmark generation
  • Documentation (including examples)
  • Research and understanding

Disclosure

If you answered "yes" to using AI assistance, please provide a short disclosure indicating how you used AI assistance. This helps reviewers determine how much scrutiny to apply when reviewing your contribution. Example disclosures: "This PR was written primarily by Claude Code." or "I consulted ChatGPT to understand the codebase, but the proposed changes were fully authored manually by myself.".

I used ChatGPT to better understand the stdlib codebase and for guidance on Git and Make workflows. All implementation changes were authored manually.


@stdlib-js/reviewers

@stdlib-bot stdlib-bot added the Math Issue or pull request specific to math functionality. label Mar 3, 2026
@stdlib-bot
Copy link
Contributor

👋 Hi there! 👋

And thank you for opening your first pull request! We will review it shortly. 🏃 💨

Getting Started

Next Steps

  1. A project maintainer will approve GitHub Actions workflows for your PR.
  2. All CI checks must pass before your submission can be fully reviewed.
  3. You'll need to address any failures in linting or unit tests.

Running Tests Locally

You can use make to run any of the CI commands locally from the root directory of the stdlib repository:

# Run tests for all packages in the math namespace:
make test TESTS_FILTER=".*/@stdlib/math/.*"

# Run benchmarks for a specific package:
make benchmark BENCHMARKS_FILTER=".*/@stdlib/math/base/special/sin/.*"

If you haven't heard back from us within two weeks, please ping us by tagging the "reviewers" team in a comment on this PR.

If you have any further questions while waiting for a response, please join our Zulip community to chat with project maintainers and other community members.

We appreciate your contribution!

Documentation Links

@stdlib-bot stdlib-bot added First-time Contributor A pull request from a contributor who has never previously committed to the project repository. Needs Review A pull request which needs code review. labels Mar 3, 2026
@stdlib-bot
Copy link
Contributor

⚠️ Tracking Issue Closure Warning ⚠️

I noticed your PR description contains closing keywords ("Resolves", "Closes", or "Fixes") referencing a "Tracking Issue".

Why this matters:
Tracking issues should typically remain open until all related sub-issues are completed. GitHub automatically closes issues with such closing keywords when the PR is merged. For more information, see GitHub's documentation on using keywords in issues and pull requests.

Required action:
Use "Progresses" instead to reference the tracking issue without automatically closing it.

Thank you for your contribution to the project!

@stdlib-bot stdlib-bot added the Potential Duplicate There might be another pull request resolving the same issue. label Mar 4, 2026
Copy link
Member

@Planeshifter Planeshifter left a comment

Choose a reason for hiding this comment

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

Thanks for opening a PR!

Left a bunch of comments; overall, the PR will require significant clean-up, mainly ensuring to use single-precision variants of all dependencies.


-->

# trunc2
Copy link
Member

Choose a reason for hiding this comment

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

H1 should be trunc2f, not trunc2.

Suggested change
# trunc2
# trunc2f

Comment on lines +133 to +134
double y = stdlib_base_trunc2f( -4.2 );
// returns -4.0
Copy link
Member

Choose a reason for hiding this comment

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

This is a single-precision (float) function. The C usage example should use float, not double, and the literal should have the f suffix. See floor2f for reference.

Suggested change
double y = stdlib_base_trunc2f( -4.2 );
// returns -4.0
float y = stdlib_base_trunc2f( -4.2f );
// returns -4.0f

Comment on lines +167 to +176
int main( void ) {
const double x[] = { 3.14, -3.14, 0.0, 0.0 / 0.0 };

double y;
int i;
for ( i = 0; i < 4; i++ ) {
y = stdlib_base_trunc2f( x[ i ] );
printf( "trunc2f(%lf) = %lf\n", x[ i ], y );
}
}
Copy link
Member

Choose a reason for hiding this comment

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

The C example section uses double throughout but this is a float function. Array should be const float x[] with f-suffixed literals, y should be float, and printf should use %f not %lf. Compare with floor2f.

Suggested change
int main( void ) {
const double x[] = { 3.14, -3.14, 0.0, 0.0 / 0.0 };
double y;
int i;
for ( i = 0; i < 4; i++ ) {
y = stdlib_base_trunc2f( x[ i ] );
printf( "trunc2f(%lf) = %lf\n", x[ i ], y );
}
}
int main( void ) {
const float x[] = { 3.14f, -3.14f, 0.0f, 0.0f / 0.0f };
float y;
int i;
for ( i = 0; i < 4; i++ ) {
y = stdlib_base_trunc2f( x[ i ] );
printf( "trunc2f(%f) = %f\n", x[ i ], y );
}
}

Comment on lines +23 to +65
var isnan = require( '@stdlib/math/base/assert/is-nan' );
var isInfinite = require( '@stdlib/math/base/assert/is-infinite' );
var pow = require( '@stdlib/math/base/special/pow' );
var floor = require( '@stdlib/math/base/special/floor' );
var log2 = require( '@stdlib/math/base/special/log2' );


// MAIN //

/**
* Rounds a numeric value to the nearest power of two toward zero.
*
* @param {number} x - input value
* @returns {number} rounded value
*
* @example
* var v = trunc2f( 3.141592653589793 );
* // returns 2.0
*
* @example
* var v = trunc2f( 13.0 );
* // returns 8.0
*
* @example
* var v = trunc2f( -0.314 );
* // returns -0.25
*/
function trunc2f( x ) {
var sign;
if (
isnan( x ) ||
isInfinite( x ) ||
x === 0.0
) {
return x;
}
if ( x < 0 ) {
x = -x;
sign = -1.0;
} else {
sign = 1.0;
}
return sign * pow( 2.0, floor( log2( x ) ) );
Copy link
Member

Choose a reason for hiding this comment

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

This is a single-precision function but the implementation operates entirely in double precision. Compare with floor2f/lib/main.js which uses isnanf, isInfinitef, powf, floorf, f32() wrappers, and float32 constants.

At minimum you need:

  • isnanf / isInfinitef instead of isnan / isInfinite
  • powf instead of pow
  • floorf instead of floor
  • f32() conversions at key points to ensure single-precision semantics
  • Float32 constants (ZERO, TWO, ONE) like floor2f does

Without these, the function produces double-precision results, which defeats the purpose of the f suffix.

Comment on lines +44 to +56
if ( stdlib_base_is_nan( x ) || stdlib_base_is_infinite( x ) || x == 0.0f ) {
return x;
}

if ( x < 0.0f ) {
sign = -1.0f;
} else {
sign = 1.0f;
}
ax = stdlib_base_absf( x );
stdlib_base_frexpf( x,&frac ,&exp );

return sign * stdlib_base_ldexpf( 1.0f, exp-1 );
Copy link
Member

Choose a reason for hiding this comment

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

Two issues here:

  1. stdlib_base_is_nan and stdlib_base_is_infinite are double-precision checks. For a float function, use stdlib_base_is_nanf and stdlib_base_is_infinitef (from is_nanf.h / is_infinitef.h).

  2. ax is computed but never used -- frexpf is called with x (which can be negative) instead of ax. Either use ax as the argument to frexpf, or remove ax and the absf include entirely since frexpf handles the sign via the exponent anyway.

Also, spacing: &frac ,&exp should be &frac, &exp.

Comment on lines +40 to +66
"dependencies": [
"@stdlib/math/base/napi/unary",
"@stdlib/math/base/special/frexpf",
"@stdlib/math/base/special/ldexpf",
"@stdlib/math/base/assert/is-nan",
"@stdlib/math/base/assert/is-infinite"
]
},
{
"task": "benchmark",
"src": [
"./src/main.c"
],
"include": [
"./include"
],
"libraries": [
"-lm"
],
"libpath": [],
"dependencies": [
"@stdlib/math/base/napi/unary",
"@stdlib/math/base/special/frexpf",
"@stdlib/math/base/special/ldexpf",
"@stdlib/math/base/assert/is-nan",
"@stdlib/math/base/assert/is-infinite"
]
Copy link
Member

Choose a reason for hiding this comment

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

The manifest.json dependencies don't match what src/main.c actually uses. Currently listed: frexpf, ldexpf, is-nan, is-infinite. But main.c also includes absf and float32/base/exponent (unused). And is-nan/is-infinite should be is-nanf/is-infinitef once main.c is fixed.

Please reconcile these -- the deps should exactly match what the C code #includes. Also, benchmark and examples tasks should not include @stdlib/math/base/napi/unary (that's only needed for the build task). See floor2f/manifest.json for reference.

v = trunc2f( Math.fround(x + Math.fround(x/3.0)) );
t.strictEqual( v, expected, 'returns expected value' );

expected = -SMALLEST_SUBNORMAL
Copy link
Member

Choose a reason for hiding this comment

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

Missing semicolon:

Suggested change
expected = -SMALLEST_SUBNORMAL
expected = -SMALLEST_SUBNORMAL;

t.end();
});

tape( 'the function returns the minimum double-precision floating-point value if provided the minimum double-precision floating-point value', function test( t ) {
Copy link
Member

Choose a reason for hiding this comment

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

This says "double-precision" but should be "single-precision" since this is a float32 function. Also, the reference package uses isnanf instead of isnan.

Suggested change
tape( 'the function returns the minimum double-precision floating-point value if provided the minimum double-precision floating-point value', function test( t ) {
tape( 'the function returns the minimum single-precision floating-point value if provided the minimum single-precision floating-point value', function test( t ) {

t.end();
});

tape( 'the function returns the minimum double-precision floating-point value if provided the minimum double-precision floating-point value', opts, function test( t ) {
Copy link
Member

Choose a reason for hiding this comment

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

Same as test.js -- "double-precision" should be "single-precision".

Suggested change
tape( 'the function returns the minimum double-precision floating-point value if provided the minimum double-precision floating-point value', opts, function test( t ) {
tape( 'the function returns the minimum single-precision floating-point value if provided the minimum single-precision floating-point value', opts, function test( t ) {

Comment on lines +22 to +23
#include "stdlib/number/float32/base/exponent.h"
#include "stdlib/math/base/special/frexpf.h"
Copy link
Member

Choose a reason for hiding this comment

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

float32/base/exponent is included but never used. Remove this unused include.

Suggested change
#include "stdlib/number/float32/base/exponent.h"
#include "stdlib/math/base/special/frexpf.h"
#include "stdlib/math/base/special/frexpf.h"

@Planeshifter Planeshifter added Needs Changes Pull request which needs changes before being merged. and removed Needs Review A pull request which needs code review. labels Mar 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

First-time Contributor A pull request from a contributor who has never previously committed to the project repository. Math Issue or pull request specific to math functionality. Needs Changes Pull request which needs changes before being merged. Potential Duplicate There might be another pull request resolving the same issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[RFC]: Add C implementations to base special math functions (tracking issue)

3 participants