1# Working with BigInt Using JSVM-API
2
3## Introduction
4
5BigInt is a data type used to represent integers of any precision in JavaScript (JS), with values greater than the value range of the Number type. You can use JSVM-API to create, obtain, and operate JS BigInt values.
6
7## Basic Concepts
8
9Before using JSVM-API to operate BigInt values, you need to understand the following basic concepts:
10
11- BigInt: a data type used to represent integers of any precision in JS. Different from the Number type, BigInt can accurately represent very large integers without losing precision or causing overflows.
12- BigInt creation: You can use JSVM-API to create a JS BigInt object from a C **Int64** or **Uint64** value. This makes it easy to create BigInt values using C/C++.
13- BigInt operation: JSVM-API provides APIs for operating BigInt values. You can use these APIs to obtain and convert BigInt values and perform arithmetic and bitwise operations.
14
15## Available APIs
16
17| API                        | Description                                |
18| ---------------------------- | ---------------------------------------- |
19| OH_JSVM_CreateBigintInt64     | Creates a JS BigInt object from a C int64_t object.|
20| OH_JSVM_CreateBigintUint64    | Creates a JS BigInt object from a C uint64_t object.|
21| OH_JSVM_CreateBigintWords     | Creates a JS BigInt object from a C uint64_t array.|
22| OH_JSVM_GetValueBigintInt64  | Obtains the C int64_t primitive equivalent of the given JS BigInt. If necessary, it truncates the value and sets **lossless** to **false**.      |
23| OH_JSVM_GetValueBigintUint64 | Obtains the C uint64_t primitive equivalent of the given JS BigInt. If necessary, it truncates the value and sets **lossless** to **false**.     |
24| OH_JSVM_GetValueBigintWords  | Obtains the underlying data (word representation) of a given JS BigInt object. The word representation includes a sign bit, a 64-bit little-endian array, and the length of the array. If **signBit** and **words** are set to **NULL**, only **wordCount** is obtained.|
25
26## Example
27
28If you are just starting out with JSVM-API, see [JSVM-API Development Process](use-jsvm-process.md). The following demonstrates only the C++ code related to BigInt operations.
29
30### OH_JSVM_GetValueBigintWords
31
32Use **OH_JSVM_GetValueBigintWords** to obtain the underlying data of a given JS BigInt object, that is, the word representation of BigInt data.
33
34CPP code:
35
36```cpp
37// hello.cpp
38#include "napi/native_api.h"
39#include "ark_runtime/jsvm.h"
40#include <hilog/log.h>
41// Define OH_JSVM_GetValueBigintWords.
42static JSVM_Value GetValueBigintWords(JSVM_Env env, JSVM_CallbackInfo info)
43   {
44    size_t argc = 1;
45    JSVM_Value args[1] = {nullptr};
46    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
47    int signBit = 0;
48    size_t wordCount = 0;
49    uint64_t* words{nullptr};
50    // Call OH_JSVM_GetValueBigintWords to obtain wordCount.
51    JSVM_Status status = OH_JSVM_GetValueBigintWords(env, args[0], nullptr, &wordCount, nullptr);
52    OH_LOG_INFO(LOG_APP, "OH_JSVM_GetValueBigintWords wordCount:%{public}d.", wordCount);
53    words = (uint64_t*)malloc(wordCount*sizeof(uint64_t));
54    if (words == nullptr) {
55        OH_LOG_ERROR(LOG_APP, "OH_JSVM_GetValueBigintWords malloc failed.");
56        return nullptr;
57    }
58    // Call OH_JSVM_GetValueBigintWords to obtain BigInt information, such as whether the value passed by signBit is a positive or negative number.
59    status = OH_JSVM_GetValueBigintWords(env, args[0], &signBit, &wordCount, words);
60    free(words);
61    words = nullptr;
62    if (status != JSVM_OK) {
63        OH_LOG_ERROR(LOG_APP, "OH_JSVM_GetValueBigintWords fail, status:%{public}d.", status);
64    } else {
65        OH_LOG_INFO(LOG_APP, "OH_JSVM_GetValueBigintWords signBit: %{public}d.", signBit);
66    }
67    // Convert the sign bit into a value of Int type and pass it.
68    JSVM_Value returnValue = nullptr;
69    OH_JSVM_CreateInt32(env, signBit, &returnValue);
70    return returnValue;
71}
72// Register the GetValueBigintWords callback.
73static JSVM_CallbackStruct param[] = {
74    {.data = nullptr, .callback = GetValueBigintWords},
75};
76static JSVM_CallbackStruct *method = param;
77// Set a property descriptor named getValueBigintWords and associate it with a callback. This allows the GetValueBigintWords callback to be called from JS.
78static JSVM_PropertyDescriptor descriptor[] = {
79    {"getValueBigintWords", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
80};
81// Call the C++ code from JS.
82const char* srcCallNative = R"JS(getValueBigintWords(BigInt(5555555555555555)))JS";
83```
84
85**Expected output**
86```ts
87OH_JSVM_GetValueBigintWords wordCount:1.
88OH_JSVM_GetValueBigintWords signBit: 1.
89```
90
91### OH_JSVM_CreateBigintWords
92
93Use **OH_JSVM_GetValueBigintWords** to create a JS BigInt object from a C uint64_t array.
94
95CPP code:
96
97```cpp
98// hello.cpp
99#include "napi/native_api.h"
100#include "ark_runtime/jsvm.h"
101#include <hilog/log.h>
102// Define OH_JSVM_CreateBigintWords.
103static int DIFF_VALUE_THREE = 3;
104static JSVM_Value CreateBigintWords(JSVM_Env env, JSVM_CallbackInfo info)
105{
106    // Call OH_JSVM_CreateBigintWords to create a BigInt object.
107    int signBit = 0;
108    size_t wordCount = DIFF_VALUE_THREE;
109    uint64_t words[] = {12ULL, 34ULL, 56ULL};
110    JSVM_Value returnValue = nullptr;
111    JSVM_Status status = OH_JSVM_CreateBigintWords(env, signBit, wordCount, words, &returnValue);
112    if (status != JSVM_OK) {
113        OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CreateBigintWords fail");
114    } else {
115        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CreateBigintWords success");
116    }
117    return returnValue;
118}
119// Register the CreateBigintWords callback.
120static JSVM_CallbackStruct param[] = {
121    {.data = nullptr, .callback = CreateBigintWords},
122};
123static JSVM_CallbackStruct *method = param;
124// Set a property descriptor named createBigintWords and associate it with a callback. This allows the CreateBigintWords callback to be called from JS.
125static JSVM_PropertyDescriptor descriptor[] = {
126    {"createBigintWords", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
127};
128// Call the C++ code from JS.
129const char* srcCallNative = R"JS(createBigintWords())JS";
130```
131
132**Expected output**
133```ts
134JSVM OH_JSVM_CreateBigintWords success
135```
136
137### OH_JSVM_CreateBigintUint64
138
139Use **OH_JSVM_CreateBigintUint64** to create a JS BigInt object from a C Uint64 object.
140
141CPP code:
142
143```cpp
144// hello.cpp
145#include "napi/native_api.h"
146#include "ark_runtime/jsvm.h"
147#include <hilog/log.h>
148// Declare the variable value of uint64_t.
149static uint64_t TEST_VALUE = 5555555555555555555;
150// Define OH_JSVM_CreateBigintUint64.
151static JSVM_Value CreateBigintUint64(JSVM_Env env, JSVM_CallbackInfo info)
152{
153    // Convert value to the JSVM_Value type and return the value.
154    JSVM_Value returnValue = nullptr;
155    JSVM_Status status = OH_JSVM_CreateBigintUint64(env, TEST_VALUE, &returnValue);
156    if (status != JSVM_OK) {
157        OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CreateBigintUint64 fail");
158    } else {
159        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CreateBigintUint64 success");
160    }
161    return returnValue;
162}
163// Define CreateBigintUint64.
164static JSVM_CallbackStruct param[] = {
165    {.data = nullptr, .callback = CreateBigintUint64},
166};
167static JSVM_CallbackStruct *method = param;
168// Set a property descriptor named createBigintUint64 and associate it with a callback. This allows the CreateBigintUint64 callback to be called from JS.
169static JSVM_PropertyDescriptor descriptor[] = {
170    {"createBigintUint64", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
171};
172// Call the C++ code from JS.
173const char* srcCallNative = R"JS(createBigintUint64())JS";
174```
175
176**Expected output**
177```ts
178JSVM OH_JSVM_CreateBigintUint64 success
179
180```
181
182### OH_JSVM_GetValueBigintUint64
183
184Use **OH_JSVM_GetValueBigintUint64** to obtain the C uint64_t primitive equivalent of the given JS BigInt object.
185
186CPP code:
187
188```cpp
189// hello.cpp
190#include "napi/native_api.h"
191#include "ark_runtime/jsvm.h"
192#include <hilog/log.h>
193// Define OH_JSVM_GetValueBigintUint64.
194static JSVM_Value GetValueBigintUint64(JSVM_Env env, JSVM_CallbackInfo info)
195{
196    size_t argc = 1;
197    JSVM_Value args[1] = {nullptr};
198    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
199    // Obtain the BigInt value.
200    uint64_t value = 0;
201    bool lossLess = false;
202    OH_JSVM_GetValueBigintUint64(env, args[0], &value, &lossLess);
203    // Check whether the BigInt value obtained is a product of lossless conversion. If no, an exception is thrown.
204    if (!lossLess) {
205        OH_JSVM_ThrowError(env, nullptr, "BigInt values have no lossless converted");
206        return nullptr;
207    } else {
208        OH_LOG_INFO(LOG_APP, "JSVM GetValueBigintUint64 success:%{public}d", lossLess);
209    }
210    JSVM_Value returnValue = nullptr;
211    OH_JSVM_CreateBigintUint64(env, value, &returnValue);
212    return returnValue;
213}
214// Register the GetValueBigintUint64 callback.
215static JSVM_CallbackStruct param[] = {
216    {.data = nullptr, .callback = GetValueBigintUint64},
217};
218static JSVM_CallbackStruct *method = param;
219// Set a property descriptor named getValueBigintUint64 and associate it with a callback. This allows the GetValueBigintUint64 callback to be called from JS.
220static JSVM_PropertyDescriptor descriptor[] = {
221    {"getValueBigintUint64", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
222};
223// Call the C++ code from JS.
224const char* srcCallNative = R"JS(getValueBigintUint64(BigInt(5555555555555555)))JS";
225```
226
227**Expected output**
228```ts
229JSVM GetValueBigintUint64 success:1
230```
231
232### OH_JSVM_CreateBigintInt64
233
234Creates a JS BigInt object from a C Uint64 object.
235
236CPP code:
237
238```cpp
239// hello.cpp
240#include "napi/native_api.h"
241#include "ark_runtime/jsvm.h"
242#include <hilog/log.h>
243// Declare the variable value of int64_t.
244static int64_t TEST_VALUE_DEMO = -5555555555555555555;
245// Define OH_JSVM_CreateBigintInt64.
246static JSVM_Value CreateBigintInt64(JSVM_Env env, JSVM_CallbackInfo info)
247{
248    JSVM_Value returnValue = nullptr;
249    JSVM_Status status = OH_JSVM_CreateBigintInt64(env, TEST_VALUE_DEMO, &returnValue);
250    if (status != JSVM_OK) {
251        OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_CreateBigintInt64 fail");
252    } else {
253        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_CreateBigintInt64 success");
254    }
255    return returnValue;
256}
257// Register the CreateBigintInt64 callback.
258static JSVM_CallbackStruct param[] = {
259    {.data = nullptr, .callback = CreateBigintInt64},
260};
261static JSVM_CallbackStruct *method = param;
262// Set a property descriptor named createBigintInt64 and associate it with a callback. This allows the CreateBigintInt64 callback to be called from JS.
263static JSVM_PropertyDescriptor descriptor[] = {
264    {"createBigintInt64", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
265};
266// Call the C++ code from JS.
267const char* srcCallNative = R"JS(createBigintInt64())JS";
268```
269
270**Expected output**
271```ts
272JSVM OH_JSVM_CreateBigintInt64 success
273```
274
275### OH_JSVM_GetValueBigintInt64
276
277Use OH_JSVM_GetValueBigintInt64 to obtain the C int64_t primitive equivalent of the given JS BigInt object.
278
279CPP code:
280
281```cpp
282// hello.cpp
283#include "napi/native_api.h"
284#include "ark_runtime/jsvm.h"
285#include <hilog/log.h>
286// Define OH_JSVM_GetValueBigintInt64.
287static JSVM_Value GetBigintInt64(JSVM_Env env, JSVM_CallbackInfo info)
288{
289    size_t argc = 1;
290    JSVM_Value args[1] = {nullptr};
291    OH_JSVM_GetCbInfo(env, info, &argc, args, nullptr, nullptr);
292    // Obtain the 64-bit big integer from the input parameter.
293    int64_t value;
294    bool lossLess;
295    OH_JSVM_GetValueBigintInt64(env, args[0], &value, &lossLess);
296    // Check whether the BigInt value obtained is a product of lossless conversion. If no, an exception is thrown.
297    if (!lossLess) {
298        OH_JSVM_ThrowError(env, nullptr, "BigInt values have no lossless converted");
299        return nullptr;
300    } else {
301        OH_LOG_INFO(LOG_APP, "JSVM GetBigintInt64 success:%{public}d", lossLess);
302    }
303    JSVM_Value returnValue = nullptr;
304    OH_JSVM_CreateBigintInt64(env, value, &returnValue);
305    return returnValue;
306}
307// Register the GetBigintInt64 callback.
308static JSVM_CallbackStruct param[] = {
309    {.data = nullptr, .callback = GetBigintInt64},
310};
311static JSVM_CallbackStruct *method = param;
312// Set a property descriptor named getBigintInt64 and associate it with a callback. This allows the GetBigintInt64 callback to be called from JS.
313static JSVM_PropertyDescriptor descriptor[] = {
314    {"getBigintInt64", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
315};
316// Call the C++ code from JS.
317const char* srcCallNative = R"JS(getBigintInt64(BigInt(-5555555555555555)))JS";
318```
319
320**Expected output**
321```ts
322JSVM GetBigintInt64 success:1
323```
324