1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
|
<!DOCTYPE html>
<html>
<head>
<title>ffi.* API Functions</title>
<meta charset="utf-8">
<meta name="Copyright" content="Copyright (C) 2005-2022">
<meta name="Language" content="en">
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
<style type="text/css">
table.abitable { width: 30em; line-height: 1.2; }
tr.abihead td { font-weight: bold; }
td.abiparam { font-weight: bold; width: 6em; }
</style>
</head>
<body>
<div id="site">
<a href="https://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
</div>
<div id="head">
<h1><tt>ffi.*</tt> API Functions</h1>
</div>
<div id="nav">
<ul><li>
<a href="luajit.html">LuaJIT</a>
<ul><li>
<a href="https://luajit.org/download.html">Download <span class="ext">»</span></a>
</li><li>
<a href="install.html">Installation</a>
</li><li>
<a href="running.html">Running</a>
</li></ul>
</li><li>
<a href="extensions.html">Extensions</a>
<ul><li>
<a href="ext_ffi.html">FFI Library</a>
<ul><li>
<a href="ext_ffi_tutorial.html">FFI Tutorial</a>
</li><li>
<a class="current" href="ext_ffi_api.html">ffi.* API</a>
</li><li>
<a href="ext_ffi_semantics.html">FFI Semantics</a>
</li></ul>
</li><li>
<a href="ext_buffer.html">String Buffers</a>
</li><li>
<a href="ext_jit.html">jit.* Library</a>
</li><li>
<a href="ext_c_api.html">Lua/C API</a>
</li><li>
<a href="ext_profiler.html">Profiler</a>
</li></ul>
</li><li>
<a href="status.html">Status</a>
</li><li>
<a href="faq.html">FAQ</a>
</li><li>
<a href="https://luajit.org/list.html">Mailing List <span class="ext">»</span></a>
</li></ul>
</div>
<div id="main">
<p>
This page describes the API functions provided by the FFI library in
detail. It's recommended to read through the
<a href="ext_ffi.html">introduction</a> and the
<a href="ext_ffi_tutorial.html">FFI tutorial</a> first.
</p>
<h2 id="glossary">Glossary</h2>
<ul>
<li><b>cdecl</b> — An abstract C type declaration (a Lua
string).</li>
<li><b>ctype</b> — A C type object. This is a special kind of
<b>cdata</b> returned by <tt>ffi.typeof()</tt>. It serves as a
<b>cdata</b> <a href="#ffi_new">constructor</a> when called.</li>
<li><b>cdata</b> — A C data object. It holds a value of the
corresponding <b>ctype</b>.</li>
<li><b>ct</b> — A C type specification which can be used for
most of the API functions. Either a <b>cdecl</b>, a <b>ctype</b> or a
<b>cdata</b> serving as a template type.</li>
<li><b>cb</b> — A callback object. This is a C data object
holding a special function pointer. Calling this function from
C code runs an associated Lua function.</li>
<li><b>VLA</b> — A variable-length array is declared with a
<tt>?</tt> instead of the number of elements, e.g. <tt>"int[?]"</tt>.
The number of elements (<tt>nelem</tt>) must be given when it's
<a href="#ffi_new">created</a>.</li>
<li><b>VLS</b> — A variable-length struct is a <tt>struct</tt> C
type where the last element is a <b>VLA</b>. The same rules for
declaration and creation apply.</li>
</ul>
<h2 id="decl">Declaring and Accessing External Symbols</h2>
<p>
External symbols must be declared first and can then be accessed by
indexing a <a href="ext_ffi_semantics.html#clib">C library
namespace</a>, which automatically binds the symbol to a specific
library.
</p>
<h3 id="ffi_cdef"><tt>ffi.cdef(def)</tt></h3>
<p>
Adds multiple C declarations for types or external symbols (named
variables or functions). <tt>def</tt> must be a Lua string. It's
recommended to use the syntactic sugar for string arguments as
follows:
</p>
<pre class="code">
ffi.cdef[[
<span style="color:#00a000;">typedef struct foo { int a, b; } foo_t; // Declare a struct and typedef.
int dofoo(foo_t *f, int n); /* Declare an external C function. */</span>
]]
</pre>
<p>
The contents of the string (the part in green above) must be a
sequence of
<a href="ext_ffi_semantics.html#clang">C declarations</a>,
separated by semicolons. The trailing semicolon for a single
declaration may be omitted.
</p>
<p>
Please note, that external symbols are only <em>declared</em>, but they
are <em>not bound</em> to any specific address, yet. Binding is
achieved with C library namespaces (see below).
</p>
<p style="color: #c00000;">
C declarations are not passed through a C pre-processor,
yet. No pre-processor tokens are allowed, except for
<tt>#pragma pack</tt>. Replace <tt>#define</tt> in existing
C header files with <tt>enum</tt>, <tt>static const</tt>
or <tt>typedef</tt> and/or pass the files through an external
C pre-processor (once). Be careful not to include unneeded or
redundant declarations from unrelated header files.
</p>
<h3 id="ffi_C"><tt>ffi.C</tt></h3>
<p>
This is the default C library namespace — note the
uppercase <tt>'C'</tt>. It binds to the default set of symbols or
libraries on the target system. These are more or less the same as a
C compiler would offer by default, without specifying extra link
libraries.
</p>
<p>
On POSIX systems, this binds to symbols in the default or global
namespace. This includes all exported symbols from the executable and
any libraries loaded into the global namespace. This includes at least
<tt>libc</tt>, <tt>libm</tt>, <tt>libdl</tt> (on Linux),
<tt>libgcc</tt> (if compiled with GCC), as well as any exported
symbols from the Lua/C API provided by LuaJIT itself.
</p>
<p>
On Windows systems, this binds to symbols exported from the
<tt>*.exe</tt>, the <tt>lua51.dll</tt> (i.e. the Lua/C API
provided by LuaJIT itself), the C runtime library LuaJIT was linked
with (<tt>msvcrt*.dll</tt>), <tt>kernel32.dll</tt>,
<tt>user32.dll</tt> and <tt>gdi32.dll</tt>.
</p>
<h3 id="ffi_load"><tt>clib = ffi.load(name [,global])</tt></h3>
<p>
This loads the dynamic library given by <tt>name</tt> and returns
a new C library namespace which binds to its symbols. On POSIX
systems, if <tt>global</tt> is <tt>true</tt>, the library symbols are
loaded into the global namespace, too.
</p>
<p>
If <tt>name</tt> is a path, the library is loaded from this path.
Otherwise <tt>name</tt> is canonicalized in a system-dependent way and
searched in the default search path for dynamic libraries:
</p>
<p>
On POSIX systems, if the name contains no dot, the extension
<tt>.so</tt> is appended. Also, the <tt>lib</tt> prefix is prepended
if necessary. So <tt>ffi.load("z")</tt> looks for <tt>"libz.so"</tt>
in the default shared library search path.
</p>
<p>
On Windows systems, if the name contains no dot, the extension
<tt>.dll</tt> is appended. So <tt>ffi.load("ws2_32")</tt> looks for
<tt>"ws2_32.dll"</tt> in the default DLL search path.
</p>
<h2 id="create">Creating cdata Objects</h2>
<p>
The following API functions create cdata objects (<tt>type()</tt>
returns <tt>"cdata"</tt>). All created cdata objects are
<a href="ext_ffi_semantics.html#gc">garbage collected</a>.
</p>
<h3 id="ffi_new"><tt>cdata = ffi.new(ct [,nelem] [,init...])<br>
cdata = <em>ctype</em>([nelem,] [init...])</tt></h3>
<p>
Creates a cdata object for the given <tt>ct</tt>. VLA/VLS types
require the <tt>nelem</tt> argument. The second syntax uses a ctype as
a constructor and is otherwise fully equivalent.
</p>
<p>
The cdata object is initialized according to the
<a href="ext_ffi_semantics.html#init">rules for initializers</a>,
using the optional <tt>init</tt> arguments. Excess initializers cause
an error.
</p>
<p>
Performance notice: if you want to create many objects of one kind,
parse the cdecl only once and get its ctype with
<tt>ffi.typeof()</tt>. Then use the ctype as a constructor repeatedly.
</p>
<p style="font-size: 8pt;">
Please note, that an anonymous <tt>struct</tt> declaration implicitly
creates a new and distinguished ctype every time you use it for
<tt>ffi.new()</tt>. This is probably <b>not</b> what you want,
especially if you create more than one cdata object. Different anonymous
<tt>structs</tt> are not considered assignment-compatible by the
C standard, even though they may have the same fields! Also, they
are considered different types by the JIT-compiler, which may cause an
excessive number of traces. It's strongly suggested to either declare
a named <tt>struct</tt> or <tt>typedef</tt> with <tt>ffi.cdef()</tt>
or to create a single ctype object for an anonymous <tt>struct</tt>
with <tt>ffi.typeof()</tt>.
</p>
<h3 id="ffi_typeof"><tt>ctype = ffi.typeof(ct)</tt></h3>
<p>
Creates a ctype object for the given <tt>ct</tt>.
</p>
<p>
This function is especially useful to parse a cdecl only once and then
use the resulting ctype object as a <a href="#ffi_new">constructor</a>.
</p>
<h3 id="ffi_cast"><tt>cdata = ffi.cast(ct, init)</tt></h3>
<p>
Creates a scalar cdata object for the given <tt>ct</tt>. The cdata
object is initialized with <tt>init</tt> using the "cast" variant of
the <a href="ext_ffi_semantics.html#convert">C type conversion
rules</a>.
</p>
<p>
This functions is mainly useful to override the pointer compatibility
checks or to convert pointers to addresses or vice versa.
</p>
<h3 id="ffi_metatype"><tt>ctype = ffi.metatype(ct, metatable)</tt></h3>
<p>
Creates a ctype object for the given <tt>ct</tt> and associates it with
a metatable. Only <tt>struct</tt>/<tt>union</tt> types, complex numbers
and vectors are allowed. Other types may be wrapped in a
<tt>struct</tt>, if needed.
</p>
<p>
The association with a metatable is permanent and cannot be changed
afterwards. Neither the contents of the <tt>metatable</tt> nor the
contents of an <tt>__index</tt> table (if any) may be modified
afterwards. The associated metatable automatically applies to all uses
of this type, no matter how the objects are created or where they
originate from. Note that predefined operations on types have
precedence (e.g. declared field names cannot be overridden).
</p>
<p>
All standard Lua metamethods are implemented. These are called directly,
without shortcuts, and on any mix of types. For binary operations, the
left operand is checked first for a valid ctype metamethod. The
<tt>__gc</tt> metamethod only applies to <tt>struct</tt>/<tt>union</tt>
types and performs an implicit <a href="#ffi_gc"><tt>ffi.gc()</tt></a>
call during creation of an instance.
</p>
<h3 id="ffi_gc"><tt>cdata = ffi.gc(cdata, finalizer)</tt></h3>
<p>
Associates a finalizer with a pointer or aggregate cdata object. The
cdata object is returned unchanged.
</p>
<p>
This function allows safe integration of unmanaged resources into the
automatic memory management of the LuaJIT garbage collector. Typical
usage:
</p>
<pre class="code">
local p = ffi.gc(ffi.C.malloc(n), ffi.C.free)
...
p = nil -- Last reference to p is gone.
-- GC will eventually run finalizer: ffi.C.free(p)
</pre>
<p>
A cdata finalizer works like the <tt>__gc</tt> metamethod for userdata
objects: when the last reference to a cdata object is gone, the
associated finalizer is called with the cdata object as an argument. The
finalizer can be a Lua function or a cdata function or cdata function
pointer. An existing finalizer can be removed by setting a <tt>nil</tt>
finalizer, e.g. right before explicitly deleting a resource:
</p>
<pre class="code">
ffi.C.free(ffi.gc(p, nil)) -- Manually free the memory.
</pre>
<h2 id="info">C Type Information</h2>
<p>
The following API functions return information about C types.
They are most useful for inspecting cdata objects.
</p>
<h3 id="ffi_sizeof"><tt>size = ffi.sizeof(ct [,nelem])</tt></h3>
<p>
Returns the size of <tt>ct</tt> in bytes. Returns <tt>nil</tt> if
the size is not known (e.g. for <tt>"void"</tt> or function types).
Requires <tt>nelem</tt> for VLA/VLS types, except for cdata objects.
</p>
<h3 id="ffi_alignof"><tt>align = ffi.alignof(ct)</tt></h3>
<p>
Returns the minimum required alignment for <tt>ct</tt> in bytes.
</p>
<h3 id="ffi_offsetof"><tt>ofs [,bpos,bsize] = ffi.offsetof(ct, field)</tt></h3>
<p>
Returns the offset (in bytes) of <tt>field</tt> relative to the start
of <tt>ct</tt>, which must be a <tt>struct</tt>. Additionally returns
the position and the field size (in bits) for bit fields.
</p>
<h3 id="ffi_istype"><tt>status = ffi.istype(ct, obj)</tt></h3>
<p>
Returns <tt>true</tt> if <tt>obj</tt> has the C type given by
<tt>ct</tt>. Returns <tt>false</tt> otherwise.
</p>
<p>
C type qualifiers (<tt>const</tt> etc.) are ignored. Pointers are
checked with the standard pointer compatibility rules, but without any
special treatment for <tt>void *</tt>. If <tt>ct</tt> specifies a
<tt>struct</tt>/<tt>union</tt>, then a pointer to this type is accepted,
too. Otherwise the types must match exactly.
</p>
<p>
Note: this function accepts all kinds of Lua objects for the
<tt>obj</tt> argument, but always returns <tt>false</tt> for non-cdata
objects.
</p>
<h2 id="util">Utility Functions</h2>
<h3 id="ffi_errno"><tt>err = ffi.errno([newerr])</tt></h3>
<p>
Returns the error number set by the last C function call which
indicated an error condition. If the optional <tt>newerr</tt> argument
is present, the error number is set to the new value and the previous
value is returned.
</p>
<p>
This function offers a portable and OS-independent way to get and set the
error number. Note that only <em>some</em> C functions set the error
number. And it's only significant if the function actually indicated an
error condition (e.g. with a return value of <tt>-1</tt> or
<tt>NULL</tt>). Otherwise, it may or may not contain any previously set
value.
</p>
<p>
You're advised to call this function only when needed and as close as
possible after the return of the related C function. The
<tt>errno</tt> value is preserved across hooks, memory allocations,
invocations of the JIT compiler and other internal VM activity. The same
applies to the value returned by <tt>GetLastError()</tt> on Windows, but
you need to declare and call it yourself.
</p>
<h3 id="ffi_string"><tt>str = ffi.string(ptr [,len])</tt></h3>
<p>
Creates an interned Lua string from the data pointed to by
<tt>ptr</tt>.
</p>
<p>
If the optional argument <tt>len</tt> is missing, <tt>ptr</tt> is
converted to a <tt>"char *"</tt> and the data is assumed to be
zero-terminated. The length of the string is computed with
<tt>strlen()</tt>.
</p>
<p>
Otherwise <tt>ptr</tt> is converted to a <tt>"void *"</tt> and
<tt>len</tt> gives the length of the data. The data may contain
embedded zeros and need not be byte-oriented (though this may cause
endianess issues).
</p>
<p>
This function is mainly useful to convert (temporary)
<tt>"const char *"</tt> pointers returned by
C functions to Lua strings and store them or pass them to other
functions expecting a Lua string. The Lua string is an (interned) copy
of the data and bears no relation to the original data area anymore.
Lua strings are 8 bit clean and may be used to hold arbitrary,
non-character data.
</p>
<p>
Performance notice: it's faster to pass the length of the string, if
it's known. E.g. when the length is returned by a C call like
<tt>sprintf()</tt>.
</p>
<h3 id="ffi_copy"><tt>ffi.copy(dst, src, len)<br>
ffi.copy(dst, str)</tt></h3>
<p>
Copies the data pointed to by <tt>src</tt> to <tt>dst</tt>.
<tt>dst</tt> is converted to a <tt>"void *"</tt> and <tt>src</tt>
is converted to a <tt>"const void *"</tt>.
</p>
<p>
In the first syntax, <tt>len</tt> gives the number of bytes to copy.
Caveat: if <tt>src</tt> is a Lua string, then <tt>len</tt> must not
exceed <tt>#src+1</tt>.
</p>
<p>
In the second syntax, the source of the copy must be a Lua string. All
bytes of the string <em>plus a zero-terminator</em> are copied to
<tt>dst</tt> (i.e. <tt>#src+1</tt> bytes).
</p>
<p>
Performance notice: <tt>ffi.copy()</tt> may be used as a faster
(inlinable) replacement for the C library functions
<tt>memcpy()</tt>, <tt>strcpy()</tt> and <tt>strncpy()</tt>.
</p>
<h3 id="ffi_fill"><tt>ffi.fill(dst, len [,c])</tt></h3>
<p>
Fills the data pointed to by <tt>dst</tt> with <tt>len</tt> constant
bytes, given by <tt>c</tt>. If <tt>c</tt> is omitted, the data is
zero-filled.
</p>
<p>
Performance notice: <tt>ffi.fill()</tt> may be used as a faster
(inlinable) replacement for the C library function
<tt>memset(dst, c, len)</tt>. Please note the different
order of arguments!
</p>
<h2 id="target">Target-specific Information</h2>
<h3 id="ffi_abi"><tt>status = ffi.abi(param)</tt></h3>
<p>
Returns <tt>true</tt> if <tt>param</tt> (a Lua string) applies for the
target ABI (Application Binary Interface). Returns <tt>false</tt>
otherwise. The following parameters are currently defined:
</p>
<table class="abitable">
<tr class="abihead">
<td class="abiparam">Parameter</td>
<td class="abidesc">Description</td>
</tr>
<tr class="odd separate">
<td class="abiparam">32bit</td><td class="abidesc">32 bit architecture</td></tr>
<tr class="even">
<td class="abiparam">64bit</td><td class="abidesc">64 bit architecture</td></tr>
<tr class="odd separate">
<td class="abiparam">le</td><td class="abidesc">Little-endian architecture</td></tr>
<tr class="even">
<td class="abiparam">be</td><td class="abidesc">Big-endian architecture</td></tr>
<tr class="odd separate">
<td class="abiparam">fpu</td><td class="abidesc">Target has a hardware FPU</td></tr>
<tr class="even">
<td class="abiparam">softfp</td><td class="abidesc">softfp calling conventions</td></tr>
<tr class="odd">
<td class="abiparam">hardfp</td><td class="abidesc">hardfp calling conventions</td></tr>
<tr class="even separate">
<td class="abiparam">eabi</td><td class="abidesc">EABI variant of the standard ABI</td></tr>
<tr class="odd">
<td class="abiparam">win</td><td class="abidesc">Windows variant of the standard ABI</td></tr>
<tr class="even">
<td class="abiparam">uwp</td><td class="abidesc">Universal Windows Platform</td></tr>
<tr class="odd">
<td class="abiparam">gc64</td><td class="abidesc">64 bit GC references</td></tr>
</table>
<h3 id="ffi_os"><tt>ffi.os</tt></h3>
<p>
Contains the target OS name. Same contents as
<a href="ext_jit.html#jit_os"><tt>jit.os</tt></a>.
</p>
<h3 id="ffi_arch"><tt>ffi.arch</tt></h3>
<p>
Contains the target architecture name. Same contents as
<a href="ext_jit.html#jit_arch"><tt>jit.arch</tt></a>.
</p>
<h2 id="callback">Methods for Callbacks</h2>
<p>
The C types for <a href="ext_ffi_semantics.html#callback">callbacks</a>
have some extra methods:
</p>
<h3 id="callback_free"><tt>cb:free()</tt></h3>
<p>
Free the resources associated with a callback. The associated Lua
function is unanchored and may be garbage collected. The callback
function pointer is no longer valid and must not be called again
(it may be reused by a subsequently created callback).
</p>
<h3 id="callback_set"><tt>cb:set(func)</tt></h3>
<p>
Associate a new Lua function with a callback. The C type of the
callback and the callback function pointer are unchanged.
</p>
<p>
This method is useful to dynamically switch the receiver of callbacks
without creating a new callback each time and registering it again (e.g.
with a GUI library).
</p>
<h2 id="extended">Extended Standard Library Functions</h2>
<p>
The following standard library functions have been extended to work
with cdata objects:
</p>
<h3 id="tonumber"><tt>n = tonumber(cdata)</tt></h3>
<p>
Converts a number cdata object to a <tt>double</tt> and returns it as
a Lua number. This is particularly useful for boxed 64 bit
integer values. Caveat: this conversion may incur a precision loss.
</p>
<h3 id="tostring"><tt>s = tostring(cdata)</tt></h3>
<p>
Returns a string representation of the value of 64 bit integers
(<tt><b>"</b>nnn<b>LL"</b></tt> or <tt><b>"</b>nnn<b>ULL"</b></tt>) or
complex numbers (<tt><b>"</b>re±im<b>i"</b></tt>). Otherwise
returns a string representation of the C type of a ctype object
(<tt><b>"ctype<</b>type<b>>"</b></tt>) or a cdata object
(<tt><b>"cdata<</b>type<b>>: </b>address"</tt>), unless you
override it with a <tt>__tostring</tt> metamethod (see
<a href="#ffi_metatype"><tt>ffi.metatype()</tt></a>).
</p>
<h3 id="pairs"><tt>iter, obj, start = pairs(cdata)<br>
iter, obj, start = ipairs(cdata)<br></tt></h3>
<p>
Calls the <tt>__pairs</tt> or <tt>__ipairs</tt> metamethod of the
corresponding ctype.
</p>
<h2 id="literals">Extensions to the Lua Parser</h2>
<p>
The parser for Lua source code treats numeric literals with the
suffixes <tt>LL</tt> or <tt>ULL</tt> as signed or unsigned 64 bit
integers. Case doesn't matter, but uppercase is recommended for
readability. It handles decimal (<tt>42LL</tt>), hexadecimal
(<tt>0x2aLL</tt>) and binary (<tt>0b101010LL</tt>) literals.
</p>
<p>
The imaginary part of complex numbers can be specified by suffixing
number literals with <tt>i</tt> or <tt>I</tt>, e.g. <tt>12.5i</tt>.
Caveat: you'll need to use <tt>1i</tt> to get an imaginary part with
the value one, since <tt>i</tt> itself still refers to a variable
named <tt>i</tt>.
</p>
<br class="flush">
</div>
<div id="foot">
<hr class="hide">
Copyright © 2005-2022
<span class="noprint">
·
<a href="contact.html">Contact</a>
</span>
</div>
</body>
</html>
|