1# Working with Basic Data Types Using Node-API
2
3## Introduction
4
5The ArkTS Number type represents a double-precision 64-bit binary IEEE 754 value. Only integers in the range of -2^53+1 to 2^53-1 (inclusive) can be represented without loss of precision. Integers out of this range must be handled by Node-API interfaces for BigInt.
6
7## Basic Concepts
8
9Before using Node-API to create and obtain numbers, you need to understand the following concepts:
10
11- Number type<br>When using Node-API, you may need to convert values of number types between C and ArkTS. When converting the data, pay attention to the data range, signedness (signed or unsigned), and precision (single or double precision).
12- Error handling<br>You also need to use Node-API to capture and handle errors that may occur during the conversion. For example, when an integer is created, you may need to capture and handle memory allocation failures or other runtime errors.
13- Interaction between ArkTS and Node-API<br>During the development, you need to consider the interaction between ArkTS and Node-API, including how to pass the data of the number type and return the correct value.
14
15## Available APIs
16
17The following table lists the APIs provided by the Node-API module for converting number types between ArkTS and C/C++.
18| API| Description|
19| -------- | -------- |
20| napi_get_value_uint32 | Obtains a C uint32 value from an ArkTS number.|
21| napi_get_value_int32 | Obtains a C int32 value from an ArkTS number.|
22| napi_get_value_int64 | Obtains a C int64 value from an ArkTS number.|
23| napi_get_value_double | Obtains a C double value from an ArkTS number.|
24| napi_create_int32 | Creates an ArkTS number from a 32-bit signed integer.|
25| napi_create_uint32 | Creates an ArkTS number from a 32-bit unsigned integer.|
26| napi_create_int64 | Creates an ArkTS number from a 64-bit signed integer.|
27| napi_create_double | Creates an ArkTS number from a double-precision floating-point number.|
28
29## Example
30
31If you are just starting out with Node-API, see [Node-API Development Process](use-napi-process.md). The following demonstrates only the C++ and ArkTS code involved in the APIs for manipulating basic data types.
32
33### napi_get_value_uint32
34
35Use **napi_get_value_uint32** to obtain a 32-bit unsigned integer from an ArkTS number.
36
37CPP code:
38
39```cpp
40#include "napi/native_api.h"
41
42static napi_value GetValueUint32(napi_env env, napi_callback_info info)
43{
44    // Obtain the parameter of the Number type.
45    size_t argc = 1;
46    napi_value argv[1] = {nullptr};
47    // Parse the input parameters.
48    napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
49
50    uint32_t number = 0;
51    // Obtain the 32-bit unsigned integer from the input parameter.
52    napi_status status = napi_get_value_uint32(env, argv[0], &number);
53    // If the input parameter is not a number, napi_number_expected will be thrown. Set the return value of the function to nullptr.
54    if (status == napi_number_expected) {
55        return nullptr;
56    }
57    napi_value result = nullptr;
58    // Create a 32-bit unsigned integer and output the integer.
59    napi_create_uint32(env, number, &result);
60    return result;
61}
62```
63
64API declaration:
65
66```ts
67// index.d.ts
68export const getValueUint32: <T>(data: T) => number | void;
69```
70
71ArkTS code:
72
73```ts
74import hilog from '@ohos.hilog'
75import testNapi from 'libentry.so'
76
77let value = testNapi.getValueUint32<number>(111111111111);
78let data = testNapi.getValueUint32<string>("sssss");
79hilog.info(0x0000, 'Node-API', 'get_value_uint32_number %{public}d', value);
80// If "sssss" (a non-number) is passed in, undefined will be returned.
81hilog.info(0x0000, 'Node-API', 'get_value_uint32_number %{public}s', data);
82// If 100 (a number within the uint32 value range) is passed in, the original number will be returned.
83hilog.info(0x0000, 'Node-API', 'get_value_uint32_number %{public}d', testNapi.getValueUint32<number>(100));
84```
85
86### napi_get_value_int32
87
88Use **napi_get_value_int32** to convert an ArkTS value to a C int32 value.
89
90CPP code:
91
92```cpp
93#include "napi/native_api.h"
94
95static napi_value GetValueInt32(napi_env env, napi_callback_info info)
96{
97    size_t argc = 1;
98    napi_value args[1] = {nullptr};
99    int32_t result32 = 0;
100    // Parse the input parameter.
101    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
102    // Convert the parameter into a C int32 value.
103    napi_status status = napi_get_value_int32(env, args[0], &result32);
104    // If the input parameter is not a number, napi_number_expected will be thrown. Set the return value of the function to nullptr.
105    if (status == napi_number_expected) {
106        return nullptr;
107    }
108    // Call napi_create_int32 to convert the 32-bit signed integer into a napi_value and return it.
109    napi_value napiResult32 = nullptr;
110    napi_create_int32(env, result32, &napiResult32);
111    return napiResult32;
112}
113```
114
115API declaration:
116
117```ts
118// index.d.ts
119export const getValueInt32: (value: number | string) => number | void;
120```
121
122ArkTS code:
123
124```ts
125import hilog from '@ohos.hilog'
126import testNapi from 'libentry.so'
127
128// If 'ss' (a non-number) is passed in, undefined will be returned.
129hilog.info(0x0000, 'Node-API', 'get_value_int32_not_number %{public}s', testNapi.getValueInt32('ss'));
130// If 100 (a number within the int32 value range) is passed in, the original number will be returned.
131hilog.info(0x0000, 'Node-API', 'get_value_int32_number %{public}d', testNapi.getValueInt32(100));
132// If 68719476735 (which is 11111111111111111111111111111111111111111111 in binary format and corresponds to the value -1 when interpreted as an int32 number) is passed in, -1 will be returned.
133hilog.info(0x0000, 'Node-API', 'get_value_int32_oversize %{public}d', testNapi.getValueInt32(68719476735));
134// If the input number is greater than 2 <sup>31</sup>-1 and its binary format does not indicate a special number in int32 like 111111111111111111111111111111111111, the integer overflows. In this case, a number decoded from the last 32-bit binary code will be returned.
135hilog.info(0x0000, 'Node-API', 'get_value_int32_oversize %{public}d', testNapi.getValueInt32(687194767355));
136// If NaN (Not-a-Number), +Infinity (positive infinity), or -Infinity (negative infinity) is passed in, 0 will be returned.
137hilog.info(0x0000, 'Node-API', 'get_value_int32_number_NAN %{public}d', testNapi.getValueInt32(NaN));
138hilog.info(0x0000, 'Node-API', 'get_value_int32_number_+Infinity %{public}d', testNapi.getValueInt32(+Infinity));
139hilog.info(0x0000, 'Node-API', 'get_value_int32_number_-Infinity %{public}d', testNapi.getValueInt32(-Infinity));
140```
141
142### napi_get_value_int64
143
144Use **napi_get_value_int64** to convert an ArkTS value to a C int64 value.
145
146CPP code:
147
148```cpp
149#include "napi/native_api.h"
150
151static napi_value GetValueInt64(napi_env env, napi_callback_info info)
152{
153    size_t argc = 1;
154    napi_value args[1] = {nullptr};
155    int64_t result64 = 0;
156    // Parse the parameter passed in.
157    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
158    // Convert the parameter into a C int64 value.
159    napi_status status = napi_get_value_int64(env, args[0], &result64);
160    // If the input parameter is not a number, return napi_number_expected.
161    if (status == napi_number_expected) {
162        return nullptr;
163    }
164    // Call napi_create_int64 to convert the int64 value to a napi_value and return it.
165    napi_value napiResult64 = nullptr;
166    napi_create_int64(env, result64, &napiResult64);
167    return napiResult64;
168}
169```
170
171API declaration:
172
173```ts
174// index.d.ts
175export const getValueInt64: (value: number | string) => number | void;
176```
177
178ArkTS code:
179
180```ts
181import hilog from '@ohos.hilog'
182import testNapi from 'libentry.so'
183
184// If a number within the int64 value range is passed in, the original number will be returned.
185hilog.info(0x0000, 'Node-API', 'get_value_int64_number %{public}d', testNapi.getValueInt64(80));
186// If 'sAs' (a non-number) is passed in, undefined will be returned.
187hilog.info(0x0000, 'Node-API', 'get_value_int64_not_number %{public}s', testNapi.getValueInt64('sAs'));
188// If a number out of the int64 value range is passed in, it will cause integer overflow and loss of precision. The number returned is not equal to the number passed in.
189hilog.info(0x0000, 'Node-API', 'get_value_int64_number_oversize %{public}d', testNapi.getValueInt64(9223372036854775809));
190// If NaN (Not-a-Number), +Infinity (positive infinity), or -Infinity (negative infinity) is passed in, 0 will be returned.
191hilog.info(0x0000, 'Node-API', 'get_value_int64_number_NAN %{public}d', testNapi.getValueInt64(NaN));
192hilog.info(0x0000, 'Node-API', 'get_value_int64_number_+Infinity %{public}d', testNapi.getValueInt64(+Infinity));
193hilog.info(0x0000, 'Node-API', 'get_value_int64_number_-Infinity %{public}d', testNapi.getValueInt64(-Infinity));
194```
195
196### napi_get_value_double
197
198Use **napi_get_value_double** to convert an ArkTS value to a C double value.
199
200CPP code:
201
202```cpp
203#include "napi/native_api.h"
204
205static napi_value GetDouble(napi_env env, napi_callback_info info)
206{
207    size_t argc = 1;
208    napi_value args[1] = {nullptr};
209    napi_get_cb_info(env, info, &argc, args , nullptr, nullptr);
210    double value = 0;
211    napi_status status = napi_get_value_double(env, args[0], &value);
212    // If a non-number is passed in, napi_number_expected will be thrown.
213    if (status == napi_number_expected) {
214        return nullptr;
215    }
216    napi_value result = nullptr;
217    napi_create_double(env, value, &result);
218    return result;
219}
220```
221
222API declaration:
223
224```ts
225// index.d.ts
226export const getDouble: (value: number | string) => number | void;
227```
228
229ArkTS code:
230
231```ts
232import hilog from '@ohos.hilog'
233import testNapi from 'libentry.so'
234// If a number is passed in, the number will be returned.
235hilog.info(0x0000, 'Node-API', 'get_value_double_number %{public}d', testNapi.getDouble(80.885));
236// If a non-number is passed in, undefined will be returned.
237hilog.info(0x0000, 'Node-API', 'get_value_double_not_number %{public}s', testNapi.getDouble('sAs'));
238```
239
240### napi_create_int32
241
242Use **napi_create_int32** to create an ArkTS number from a 32-bit signed integer.
243
244CPP code:
245
246```cpp
247#include "napi/native_api.h"
248
249static napi_value CreateInt32(napi_env env, napi_callback_info info)
250{
251    // int32_t represents a 32-bit signed integer, ranging from -2^31 to 2^31 - 1, that is, -2147483648 to 2147483647.
252    //
253    int32_t value = -26;
254    // Create an ArkTS Int32 number.
255    napi_value result = nullptr;
256    napi_status status = napi_create_int32(env, value, &result);
257    if (status != napi_ok) {
258        // Error handling.
259        napi_throw_error(env, nullptr, "Failed to create int32 value");
260    }
261    return result;
262}
263```
264
265API declaration:
266
267```ts
268// index.d.ts
269export const createInt32: () => number;
270```
271
272ArkTS code:
273
274```ts
275import hilog from '@ohos.hilog'
276import testNapi from 'libentry.so'
277
278hilog.info(0x0000, 'testTag','Test Node-API napi_create_int32: ' + testNapi.createInt32());
279```
280
281### napi_create_uint32
282
283Use **napi_create_uint32** to create an ArkTS number from a 32-bit unsigned integer.
284
285CPP code:
286
287```cpp
288#include "napi/native_api.h"
289
290static napi_value CreateUInt32(napi_env env, napi_callback_info info)
291{
292    // If the uint32_t type is used to represent -26, overflow occurs. Modulo operation is performed on the result to convert the binary complement of the negative number to a positive number. That is, 4294967270 will be returned.
293    // uint32_t represents a 32-bit unsigned integer, ranging from 0 to 2^32 - 1, that is, 0 to 4294967295.
294    uint32_t value = 26;
295    // Create an ArkTS Uint32 number.
296    napi_value result = nullptr;
297    napi_status status = napi_create_uint32(env, value, &result);
298    if (status != napi_ok) {
299        // Error handling.
300        napi_throw_error(env, nullptr, "Failed to create uint32 value");
301    }
302    return result;
303}
304```
305
306API declaration:
307
308```ts
309// index.d.ts
310export const createUInt32: () => number;
311```
312
313ArkTS code:
314
315```ts
316import hilog from '@ohos.hilog'
317import testNapi from 'libentry.so'
318
319 hilog.info(0x0000, 'testTag','Test Node-API napi_create_uint32: ' + testNapi.createUInt32());
320```
321
322### napi_create_int64
323
324Use **napi_create_int64** to create an ArkTS number from a 64-bit signed integer.
325
326CPP code:
327
328```cpp
329#include "napi/native_api.h"
330
331static napi_value CreateInt64(napi_env env, napi_callback_info info)
332{
333    // int64 represents a 64-bit signed integer, ranging from -2^63 to 2^63 - 1, that is, -9223372036854775808 to 9223372036854775807.
334    int64_t value = 2147483648;
335    // Create an ArkTS Int64 number.
336    napi_value result = nullptr;
337    napi_status status = napi_create_int64(env, value, &result);
338    if (status != napi_ok) {
339        // Error handling.
340        napi_throw_error(env, nullptr, "Failed to create int64 value");
341    }
342    return result;
343}
344```
345
346API declaration:
347
348```ts
349// index.d.ts
350export const createInt64: () => number;
351```
352
353ArkTS code:
354
355```ts
356import hilog from '@ohos.hilog'
357import testNapi from 'libentry.so'
358
359hilog.info(0x0000, 'testTag','Test Node-API napi_create_int64: ' + testNapi.createInt64());
360```
361
362### napi_create_double
363
364Use **napi_create_double** to create an ArkTS number from a double-precision floating-point number.
365
366CPP code:
367
368```cpp
369#include "napi/native_api.h"
370
371static napi_value CreateDouble(napi_env env, napi_callback_info info)
372{
373    double value = 1.234;
374    // Create an ArkTS double number.
375    napi_value result = nullptr;
376    napi_status status = napi_create_double(env, value, &result);
377    if (status != napi_ok) {
378        // Error handling.
379        napi_throw_error(env, nullptr, "Failed to create double value");
380    }
381    return result;
382}
383```
384
385API declaration:
386
387```ts
388// index.d.ts
389export const createDouble: () => number;
390```
391
392ArkTS code:
393
394```ts
395import hilog from '@ohos.hilog'
396import testNapi from 'libentry.so'
397
398hilog.info(0x0000, 'testTag','Test Node-API napi_create_double: ' + testNapi.createDouble());
399```
400
401To print logs in the native CPP, add the following information to the **CMakeLists.txt** file and add the header file by using **#include "hilog/log.h"**.
402
403```text
404// CMakeLists.txt
405add_definitions( "-DLOG_DOMAIN=0xd0d0" )
406add_definitions( "-DLOG_TAG=\"testTag\"" )
407target_link_libraries(entry PUBLIC libhilog_ndk.z.so)
408```
409