123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566 |
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
- <html>
- <head>
- <title>ffi.* API Functions</title>
- <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
- <meta name="Author" content="Mike Pall">
- <meta name="Copyright" content="Copyright (C) 2005-2012, Mike Pall">
- <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="http://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="http://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_jit.html">jit.* Library</a>
- </li><li>
- <a href="ext_c_api.html">Lua/C API</a>
- </li></ul>
- </li><li>
- <a href="status.html">Status</a>
- <ul><li>
- <a href="changes.html">Changes</a>
- </li></ul>
- </li><li>
- <a href="faq.html">FAQ</a>
- </li><li>
- <a href="http://luajit.org/performance.html">Performance <span class="ext">»</span></a>
- </li><li>
- <a href="http://wiki.luajit.org/">Wiki <span class="ext">»</span></a>
- </li><li>
- <a href="http://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 pre-defined operations on types have
- precedence (e.g. declared field names cannot be overriden).
- </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>
- </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 anymore
- (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 both decimal (<tt>42LL</tt>) and hexadecimal
- (<tt>0x2aLL</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-2012 Mike Pall
- <span class="noprint">
- ·
- <a href="contact.html">Contact</a>
- </span>
- </div>
- </body>
- </html>
|