How to replicate Javascript's 32-bit signed integer arithmetic in C (or Perl) with a few differences

I have encountered a discrepancy when translating simple JS code to C and/or Perl, specifically related to arithmetic operations (+ - * / << >>) on integers causing overflow. My goal is to replicate the exact behavior of JS, including handling overflows. The JS variables are not explicitly BigInt, but just standard JS var.

JS (via node.js or Firefox's developer tools' console):

function calc(a, b){
 return (a<<b) + (a<<b);
}
var x = calc(1, 30);
result:
2147483648

C:

#include <stdio.h>
#include <stdint.h>
int main(void){
  int32_t lop = 1<<30; //1073741824;
  int32_t rop = 1<<30; //1073741824;
  int32_t res = lop + rop;
  printf("1<<30 + 1<<30 : %d\n", res);
}
result:
1<<30 + 1<<30 : -2147483648

Perl:

sub to32bit { unpack("l", pack("L", $_[0])) } # Corion @ PerlMonks
print to32bit(to32bit(1<<30)+to32bit(1<<30));
result:
-2147483648

Is there truly a discrepancy in my approach, or am I missing something?

How can I ensure that the C/Perl code behaves exactly like JS?

My aim is to replicate JS's precise behavior in C/Perl without altering the original JS code.

For further discussion, refer to this link.

Edit: February 2024 - A new CPAN module Math::JS (available at ) has been developed by Sisyphus.

Answer №1

JavaScript is built on ECMAScript, which dictates that a left-shift operation should be carried out by converting the left operand into a 32-bit two’s complement integer before performing the operation and converting the right operand into a 32-bit unsigned integer. It also specifies that addition should be done using numbers in the IEEE-754 binary64 (“double precision”) form.

If your C implementation utilizes binary64 for double, as is common practice, and has access to int32_t and uint32_t (found in the <stdint.h> header), then JavaScript's (a<<b) + (a<<b) can be mostly represented as:

(double) ((int32_t) a << (uint32_t) b) + (double) ((int32_t) a << (uint32_t) b)

This statement of "mostly equivalent" stems from potential variations between ECMAScript and C in handling exceptional cases, infinities, NaNs, and type conversions during operations.

The ECMAScript specification clearly outlines the semantics of operations. For those translating JavaScript into another language, it is advisable to refer to the ECMAScript Language Specification.

Answer №2

When working with Javascript numbers, it's important to note that they are essentially doubles. During bit arithmetics, they are first truncated to int32's and then promoted back to doubles. Therefore, your C code should look something like this:

double js_shift_left(double a, double b) {
    return (double) ((int32_t)a << (int32_t)b);
}

double calculate(double a, double b) {
    return js_shift_left(a, b) + js_shift_left(a, b);
}

int main(void){
  double result = calculate(1, 30);
  printf("result : %f\n", result);
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Manage the border around the image by incorporating a timer countdown - starting from a complete circle, transitioning to a partial arc, and finally disappearing completely

My expertise lies in html, css, and angularjs for front-end development. I have an image that is initially surrounded by a thick border forming a full circle. As a countdown of one minute begins, I want the border to gradually disappear as time progresses. ...

What is the best way to perform this task in Angular2?

I am currently working with three arrays: tables = [{number:1},{number:2},{number:3},{number:4}]; foods = [ {id:1, name:'Ice Cream'}, {id:2, name:'Pizza'}, {id:1, name:'Hot Dog'}, {id:2, name:'Salad'} ]; o ...

The Xero Node OAuth Authorize Callback URL is malfunctioning after granting access

When utilizing the xero-node library to produce a Request Token using the getRequestToken function, the URL provided does not automatically redirect the user to the designated callback address specified in the configuration. Instead, a screen displaying a ...

Utilizing a custom font to emphasize the extended phrase in the following sentence

I've been trying to use word-wrap to break long words into the next line, but unfortunately it's not working as expected. You can view my JsFiddle code for reference. The divs on my page are generated dynamically, and here is an overview of what ...

Don't waste time creating multiple popups for changing content - streamline your process

Challenge I've successfully extracted information from an array and displayed it dynamically in a tooltip/popup window above each photo on the page. However, with 56 different individuals at various locations, arranging them neatly in a grid poses a ...

Guide to Repairing Uncaught TypeError: players.setAttribute is not a recognized method?

I'm a beginner and encountered an error saying Uncaught TypeError: players.setAttribute is not a function when submitting an action. How can I solve this issue? Please share your insights. ''' //selecting all necessary elements const s ...

Utilize a Python script to transmit data to JavaScript through JSON in order to dynamically alter the content of

Currently, I am developing an interactive display that utilizes sensors on a raspberry pi. The display is set to show a webpage and I have implemented a python script to handle sensor interaction. My goal is to change the displayed web page when a user p ...

Select a random class from an array of classes in JavaScript

I have a collection of Classes: possibleEnemies: [ Slime, (currently only one available) ], I am trying to randomly pick one of them and assign it to a variable like this (all classes are derived from the Enemy class): this.enemy = new this.possibleEn ...

Prop in a React component is undergoing mutation

I encountered a strange situation where a prop in a React component is being changed. Although it's technically not a mutation since it's an array in JavaScript, it should not be modified. To replicate the issue, I created a simple example: htt ...

Tips for injecting animation into a DIV

I am trying to make a <div> element on my webpage expand to the full width and height of the screen. While I have managed to achieve this, I also want to implement an animation that will be displayed when the <div> enlarges to fit the screen si ...

Is it possible to assign a deconstructed array to a variable and then further deconstruct it?

Is there a way to deconstruct an array, assign it to a variable, and then pass the value to another deconstructed variable all in one line of code? Take a look at what I want to achieve below: const { prop } = [a] = chips.filter(x => x.id == 1); Typic ...

Reactjs Promise left hanging in limbo

How can I resolve the pending status of my promise? I have a modal with a form submit in it, where I am trying to retrieve the base64 string of a CSV file. While my code seems to be returning the desired result, it remains stuck in a pending state. c ...

Guide on how to toggle disabled input text box upon checking checkbox using JavaScript

When the checkbox next to the appended text box is checked, I want to disable that text box. The hard-coded text box is already disabled when its checkbox is checked. You can see the actual outcome by running the code snippet or check out the screenshots b ...

How to retrieve a random element from an array within a for loop using Angular 2

I'm in the process of developing a soundboard that will play a random sound each time a button is clicked. To achieve this, I have created an array within a for loop to extract the links to mp3 files (filename), and when a user clicks the button, the ...

The automated Login Pop Up button appears on its own and does not immediately redirect to the login form

Hey guys, I'm struggling with modifying the jquery and html to ensure that when the login button is clicked, the login form pops up instead of displaying another login button. Another issue I am facing is that the login button seems to pop up automati ...

Dealing with a checkbox click event in Vuejs when there is no parent element involvement

In the table below, you can see checkboxes displayed as images: example image of a table with checkboxes Here is an example code snippet: <tbody> <tr @click="goDetail"> <th scope="row><input type="checkbox" /></th> <t ...

Moving an item to the top of an array in JavaScript/Vue.js: A simple guide

const a = [{ "iso2": "KH", "countryName": "Cambodia", "nationality": "Cambodian" }, { "iso2": "KI", "countryName": "Kiribati", "nationality": "I-Kiribati" }, { "iso2": "KM", "countryName": "Comoros", "nationality": "Como ...

A sophisticated approach to implementing a search functionality within a complex JSON structure containing nested arrays using JavaScript

Searching for data in JSON format: { "results": { "key1": [ { "step": "step1", "result": "pass" } , { "step": "step2", "result": "pending" } ...

Try enabling automatic status bar filling in Onsen UI when working with AngularJS

Completely new to AngularJS, I am trying to understand how to use ons.enableAutoStatusBarFill(); in order to prevent my menus from overlapping the status bar. This is how I have set up my controller: var mod = ons.bootstrap('app', ['onsen& ...

Generate a JSON Object array by collecting data from various elements to make it dynamic

Seeking assistance in creating a dynamic array of JSON objects from the values of various elements. Below are some examples of these elements. There are more elements contributing to the JSON values, but I don't want to repeat the same code three time ...