1# 使用Node-API接口操作bigint类型值
2
3## 简介
4
5BigInt是ArkTS中用于表示任意精度整数的数据类型,它能够处理比Number类型更大范围的整数值。通过Node-API提供的接口,可以在Node-API模块中创建、获取和操作BigInt类型值,从而实现与BigInt相关的功能扩展。
6
7## 基本概念
8
9在使用Node-API接口操作BigInt类型值时,需要理解以下基本概念:
10
11- **BigInt类型:** BigInt是ArkTS中的一种数据类型,用于表示任意精度的整数。与Number类型不同,BigInt类型可以精确表示非常大的整数,而不会丢失精度或溢出。
12- **BigInt创建:** 使用Node-API提供的接口,可以通过传递C的int64或uint64数据来创建对应的ArkTS BigInt。这使得在Node-API模块中可以方便地创建BigInt类型值。
13- **BigInt操作:** Node-API提供了多个接口用于操作BigInt类型值。通过这些接口,可以获取BigInt的数值,进行数值转换,以及执行常见的算术和位运算操作。
14
15## 场景和功能介绍
16
17| 接口 | 描述 |
18| -------- | -------- |
19| napi_create_bigint_int64 | 用于创建64位带符号整数(int64)的BigInt对象的函数。 |
20| napi_create_bigint_uint64 | 用于创建64位无符号整数(uint64)的BigInt对象的函数。 |
21| napi_create_bigint_words | 用于根据提供的64位无符号(uint64)字节数据创建BigInt对象的函数。 |
22| napi_get_value_bigint_int64 | 用于从BigInt对象中获取64位带符号整数(int64)值的函数。 |
23| napi_get_value_bigint_uint64 | 用于从BigInt对象中获取64位无符号整数(uint64)值的函数。 |
24| napi_get_value_bigint_words | 用于从BigInt对象中获取底层的64位无符号(uint64)字节数据。 |
25
26
27## 使用示例
28
29Node-API接口开发流程参考[使用Node-API实现跨语言交互开发流程](use-napi-process.md),本文仅对接口对应C++及ArkTS相关代码进行展示。
30
31### napi_create_bigint_int64
32
33这个函数用于在给定的Node-API环境中依据一个带有符号的64位整数创建一个ArkTS的BigInt对象。
34
35cpp部分代码
36
37```cpp
38#include "napi/native_api.h"
39
40static napi_value CreateBigintInt64t(napi_env env, napi_callback_info info)
41{
42    // 声明int64_t的变量value
43    int64_t value = -5555555555555555555;
44    // 将value转化为napi_value类型返回
45    napi_value returnValue = nullptr;
46    napi_create_bigint_int64(env, value, &returnValue);
47    return returnValue;
48}
49```
50
51接口声明
52
53```ts
54// index.d.ts
55export const createBigintInt64t: () => bigint;
56```
57
58ArkTS侧示例代码
59
60```ts
61import hilog from '@ohos.hilog'
62import testNapi from 'libentry.so'
63
64hilog.info(0x0000, 'testTag', 'Test Node-API napi_create_bigint_int64: %{public}d', testNapi.createBigintInt64t());
65```
66
67### napi_create_bigint_uint64
68
69这个函数用于在给定的Node-API环境中依据一个无符号的64位整数创建一个ArkTS的BigInt对象。
70
71cpp部分代码
72
73```cpp
74#include "napi/native_api.h"
75
76static napi_value CreateBigintUint64t(napi_env env, napi_callback_info info)
77{
78    // 声明uint64_t的变量value
79    uint64_t value = 5555555555555555555;
80    // 将value转化为napi_value类型返回
81    napi_value returnValue = nullptr;
82    napi_create_bigint_uint64(env, value, &returnValue);
83    return returnValue;
84}
85```
86
87接口声明
88
89```ts
90// index.d.ts
91export const createBigintUint64t: () => bigint;
92```
93
94ArkTS侧示例代码
95
96```ts
97import hilog from '@ohos.hilog'
98import testNapi from 'libentry.so'
99
100hilog.info(0x0000, 'testTag', 'Test Node-API napi_create_bigint_uint64: %{public}d', testNapi.createBigintUint64t());
101```
102
103### napi_create_bigint_words
104
105这个函数用于在给定的Node-API环境中由一系列无符号64位整数创建一个ArkTS的BigInt对象。
106
107cpp部分代码
108
109```cpp
110#include "napi/native_api.h"
111
112static napi_value CreateBigintWords(napi_env env, napi_callback_info info)
113{
114    // 使用napi_create_bigint_words接口创建一个BigInt对象
115    int signBit = 0;
116    size_t wordCount = 3;
117    uint64_t words[] = {12ULL, 34ULL, 56ULL};
118    napi_value returnValue = nullptr;
119    napi_status status = napi_create_bigint_words(env, signBit, wordCount, words, &returnValue);
120    if (status != napi_ok) {
121        napi_throw_error(env, nullptr, "napi_create_bigint_words fail");
122        return nullptr;
123    }
124    return returnValue;
125}
126```
127
128接口声明
129
130```ts
131// index.d.ts
132export const createBigintWords: () => bigint | void;
133```
134
135ArkTS侧示例代码
136
137```ts
138import hilog from '@ohos.hilog'
139import testNapi from 'libentry.so'
140try {
141  hilog.info(0x0000, 'testTag', 'Test Node-API napi_create_bigint_words: %{public}d', testNapi.createBigintWords());
142} catch (error) {
143  hilog.error(0x0000, 'testTag', 'Test Node-API NapiGetValueBigint: %{public}s', error.message);
144}
145```
146
147### napi_get_value_bigint_int64
148
149用于从传入的参数中提取64位整数的BigInt数据,以供后续处理。
150
151cpp部分代码
152
153```cpp
154#include "napi/native_api.h"
155
156static napi_value GetValueBigintInt64t(napi_env env, napi_callback_info info)
157{
158    size_t argc = 1;
159    napi_value args[1] = {nullptr};
160    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
161    // 从传入的参数中提取64位整数的BigInt数据
162    int64_t value = 0;
163    bool lossLess = false;
164    napi_status status = napi_get_value_bigint_int64(env, args[0], &value, &lossLess);
165    // 判断从ArkTS侧获取bigint是否为无损转换,如果不是抛出异常
166    if (!lossLess) {
167        napi_throw_error(env, nullptr, "BigInt values have not been lossless converted");
168        return nullptr;
169    }
170    // 如果接口调用成功正常调用则返回true给ArkTS侧
171    napi_value returnValue = nullptr;
172    napi_get_boolean(env, status == napi_ok, &returnValue);
173    return returnValue;
174}
175```
176
177接口声明
178
179```ts
180// index.d.ts
181export const getValueBigintInt64t: (bigInt64: bigint) => boolean | void;
182```
183
184ArkTS侧示例代码
185
186```ts
187import hilog from '@ohos.hilog'
188import testNapi from 'libentry.so'
189let bigInt = BigInt(-5555555555555555);
190try {
191  hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_value_bigint_int64: %{public}s',
192             JSON.stringify(testNapi.getValueBigintInt64t(bigInt)));
193} catch (error) {
194  hilog.error(0x0000, 'testTag', 'Test Node-API NapiGetValueBigint: %{public}s', error.message);
195}
196```
197
198### napi_get_value_bigint_uint64
199
200用于从传入的参数中提取无符号64位整数的BigInt数据,以供后续处理。
201
202cpp部分代码
203
204```cpp
205#include "napi/native_api.h"
206
207static napi_value GetValueBigintUint64t(napi_env env, napi_callback_info info)
208{
209    size_t argc = 1;
210    napi_value args[1] = {nullptr};
211    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
212    // 从参数值中获取BigInt的数值
213    uint64_t value = 0;
214    bool lossLess = false;
215    napi_status status = napi_get_value_bigint_uint64(env, args[0], &value, &lossLess);
216    // 判断从ArkTS侧获取bigint是否为无损转换,如果不是抛出异常
217    if (!lossLess) {
218        napi_throw_error(env, nullptr, "BigInt values have no lossless converted");
219        return nullptr;
220    }
221    // 如果接口调用成功正常调用则返回true给ArkTS侧
222    napi_value returnValue = nullptr;
223    napi_get_boolean(env, status == napi_ok, &returnValue);
224    return returnValue;
225}
226```
227
228接口声明
229
230```ts
231// index.d.ts
232export const getValueBigintUint64t: (bigUint64: bigint) => boolean | void;
233```
234
235ArkTS侧示例代码
236
237```ts
238import hilog from '@ohos.hilog'
239import testNapi from 'libentry.so'
240let bigUint = BigInt(5555555555555555);
241try {
242  hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_value_bigint_uint64: %{public}s',
243             JSON.stringify(testNapi.getValueBigintUint64t(bigUint)));
244} catch (error) {
245  hilog.error(0x0000, 'testTag', 'Test Node-API NapiGetValueBigint: %{public}s', error.message);
246}
247```
248
249### napi_get_value_bigint_words
250
251用于获取ArkTS的BigInt对象底层的64位无符号(uint64)二进制字节数据。
252
253cpp部分代码
254
255```cpp
256#include "hilog/log.h"
257#include "napi/native_api.h"
258
259static napi_value GetValueBigintWords(napi_env env, napi_callback_info info)
260{
261    size_t argc = 1;
262    napi_value args[1] = {nullptr};
263    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
264    int signBit = 0;
265    size_t wordCount = 0;
266    uint64_t words = 0;
267    // 调用napi_get_value_bigint_words接口获取wordCount
268    napi_status status = napi_get_value_bigint_words(env, args[0], nullptr, &wordCount, nullptr);
269    OH_LOG_INFO(LOG_APP, "Node-API , wordCount:%{public}d.", wordCount);
270    // 调用napi_get_value_bigint_words接口获取传入bigInt相关信息,如:signBit传入bigInt正负信息
271    status = napi_get_value_bigint_words(env, args[0], &signBit, &wordCount, &words);
272    OH_LOG_INFO(LOG_APP, "Node-API , signBit: %{public}d.", signBit);
273    if (status != napi_ok) {
274        OH_LOG_ERROR(LOG_APP, "Node-API , reason:%{public}d.", status);
275        napi_throw_error(env, nullptr, "napi_get_date_value fail");
276        return nullptr;
277    }
278    // 将符号位转化为int类型传出去
279    napi_value returnValue = nullptr;
280    napi_create_int32(env, signBit, &returnValue);
281    return returnValue;
282}
283```
284
285接口声明
286
287```ts
288// index.d.ts
289export const getValueBigintWords: (bigIntWords: bigint) => bigint | void;
290```
291
292ArkTS侧示例代码
293
294```ts
295import hilog from '@ohos.hilog'
296import testNapi from 'libentry.so'
297let bigInt = BigInt(-5555555555555555);
298let bigUint = BigInt(5555555555555555);
299try {
300  hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_value_bigint_words signBit is: %{public}d', testNapi.getValueBigintWords(bigInt));
301  hilog.info(0x0000, 'testTag', 'Test Node-API napi_get_value_bigint_words signBit is: %{public}d', testNapi.getValueBigintWords(bigUint));
302} catch (error) {
303  hilog.error(0x0000, 'testTag', 'Test Node-API NapiGetValueBigint: %{public}s', error.message);
304}
305```
306
307以上代码如果要在native cpp中打印日志,需在CMakeLists.txt文件中添加以下配置信息(并添加头文件:#include "hilog/log.h"):
308
309```text
310// CMakeLists.txt
311add_definitions( "-DLOG_DOMAIN=0xd0d0" )
312add_definitions( "-DLOG_TAG=\"testTag\"" )
313target_link_libraries(entry PUBLIC libhilog_ndk.z.so)
314```
315