Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Welcome to Software Development on Codidact!

Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.

Post History

50%
+0 −0
Q&A Compile-time rounding with the pre-processor

I know you asked specifically about the C preprocessor, but I'm going to mention my own MPASM and ASM30 preprocessor anyway. It is called PREPIC, and is free and open source (in the Embed PIC repo...

posted 4mo ago by Olin Lathrop‭  ·  edited 4mo ago by Olin Lathrop‭

Answer
#2: Post edited by user avatar Olin Lathrop‭ · 2026-06-01T13:50:27Z (4 months ago)
  • I know you asked specifically about the C preprocessor, but I'm going to mention my own MPASM and ASM30 preprocessor anyway. It is called <a href='https://www.embedinc.com/pic/prepic.htm'>PREPIC</a>, and is free and open source (in the Embed <a href='https://www.embedinc.com/pic/prepic.htm'>PIC</a> repository on GitHub). PREPIC is actually a thin layer over the Embed generic scripting and preprocessing engine, <a href='https://www.embedinc.com/pic/prepic.htm'>ESCR</a>. That's also free and <a href='https://www.embedinc.com/pic/prepic.htm'>open source</a>.
  • This preprocessor is significantly more capable than the one that comes with C compilers. It doesn't just do string substitution hacks, but has native variables, constants, in-line functions, subroutines, and more of its own. Here is an example of using PREPIC with ASM30 to create the value Pi rounded to the nearest fixed point with 8 fraction bits, then load the result into W0 of a dsPIC:
  • <pre>
  • /var r new real ;create preprocessor variable R
  • /set r [pi 256] ;set R to Pi times 256
  • /const pifix integer = [rnd r] ;create constant PIFIX
  • mov #[v pifix], w0 ;fixed point Pi into W0
  • </pre>
  • Note that R is a preprocessor variable, and that it specifically has the type REAL (floating point). PIFIX is a preprocessor constant and has the type INTEGER.
  • Expressions in square brackets are preprocessor functions. These get expanded to their value before the assembler sees the code. The first token of each function is the function name. The PI function returns the value of Pi times the (optional) parameter. The RND function converts floating point to integer by rounding. Yes, there is also a TRUNC function. The V function returns the value of the argument. That's how the fixed point value of Pi is ultimately moved into the assembler domain.
  • The above example was more verbose than needed to illustrate a few points. It could have been:
  • <pre>
  • /const pifix integer = [rnd [pi 256]] ;create constant PIFIX
  • mov #[v pifix], w0 ;fixed point Pi into W0
  • </pre>
  • Or if the fixed point value of Pi is only used in this one place, it could have been:
  • <pre>
  • mov #[rnd [pi 256]], w0 ;fixed point Pi into W0
  • </pre>
  • ESCR is intended to allow applications (like PREPIC) to use it as a preprocessor and customize some of its features. This could be done to create a C preprocessor. C already reserves "#" for identifying preprocessor commands. The hard part would be deciding the syntax for identifying preprocessor inline functions. It would probably have to be a two-character sequence. Another possibility is that an ESCR C preprocessor only produces specific #DEFINE C macros as its output, which are then handled in the usual way. In other words, there wouldn't be any ESCR in-line functions except within ESCR preprocessor commands.
  • I know you asked specifically about the C preprocessor, but I'm going to mention my own MPASM and ASM30 preprocessor anyway. It is called <a href='https://www.embedinc.com/pic/prepic.htm'>PREPIC</a>, and is free and open source (in the Embed <a href='https://github.com/EmbedInc/pic'>PIC</a> repository on GitHub). PREPIC is actually a thin layer over the Embed generic scripting and preprocessing engine, <a href='https://www.embedinc.com/pic/escr/index.htm'>ESCR</a>. That's also free and <a href='https://github.com/EmbedInc/escr'>open source</a>.
  • This preprocessor is significantly more capable than the one that comes with C compilers. It doesn't just do string substitution hacks, but has native variables, constants, in-line functions, subroutines, and more of its own. Here is an example of using PREPIC with ASM30 to create the value Pi rounded to the nearest fixed point with 8 fraction bits, then load the result into W0 of a dsPIC:
  • <pre>
  • /var r new real ;create preprocessor variable R
  • /set r [pi 256] ;set R to Pi times 256
  • /const pifix integer = [rnd r] ;create constant PIFIX
  • mov #[v pifix], w0 ;fixed point Pi into W0
  • </pre>
  • Note that R is a preprocessor variable, and that it specifically has the type REAL (floating point). PIFIX is a preprocessor constant and has the type INTEGER.
  • Expressions in square brackets are preprocessor functions. These get expanded to their value before the assembler sees the code. The first token of each function is the function name. The PI function returns the value of Pi times the (optional) parameter. The RND function converts floating point to integer by rounding. Yes, there is also a TRUNC function. The V function returns the value of the argument. That's how the fixed point value of Pi is ultimately moved into the assembler domain.
  • The above example was more verbose than needed to illustrate a few points. It could have been:
  • <pre>
  • /const pifix integer = [rnd [pi 256]] ;create constant PIFIX
  • mov #[v pifix], w0 ;fixed point Pi into W0
  • </pre>
  • Or if the fixed point value of Pi is only used in this one place, it could have been:
  • <pre>
  • mov #[rnd [pi 256]], w0 ;fixed point Pi into W0
  • </pre>
  • ESCR is intended to allow applications (like PREPIC) to use it as a preprocessor and customize some of its features. This could be done to create a C preprocessor. C already reserves "#" for identifying preprocessor commands. The hard part would be deciding the syntax for identifying preprocessor inline functions. It would probably have to be a two-character sequence. Another possibility is that an ESCR C preprocessor only produces specific #DEFINE C macros as its output, which are then handled in the usual way. In other words, there wouldn't be any ESCR in-line functions except within ESCR preprocessor commands.
#1: Initial revision by user avatar Olin Lathrop‭ · 2026-06-01T13:46:22Z (4 months ago)
I know you asked specifically about the C preprocessor, but I'm going to mention my own MPASM and ASM30 preprocessor anyway.  It is called <a href='https://www.embedinc.com/pic/prepic.htm'>PREPIC</a>, and is free and open source (in the Embed <a href='https://www.embedinc.com/pic/prepic.htm'>PIC</a> repository on GitHub).  PREPIC is actually a thin layer over the Embed generic scripting and preprocessing engine, <a href='https://www.embedinc.com/pic/prepic.htm'>ESCR</a>.  That's also free and <a href='https://www.embedinc.com/pic/prepic.htm'>open source</a>.

This preprocessor is significantly more capable than the one that comes with C compilers.  It doesn't just do string substitution hacks, but has native variables, constants, in-line functions, subroutines, and more of its own.  Here is an example of using PREPIC with ASM30 to create the value Pi rounded to the nearest fixed point with 8 fraction bits, then load the result into W0 of a dsPIC:

<pre>
/var r new real              ;create preprocessor variable R
/set r [pi 256]              ;set R to Pi times 256
/const pifix integer = [rnd r] ;create constant PIFIX

         mov     #[v pifix], w0 ;fixed point Pi into W0
</pre>

Note that R is a preprocessor variable, and that it specifically has the type REAL (floating point).  PIFIX is a preprocessor constant and has the type INTEGER.

Expressions in square brackets are preprocessor functions.  These get expanded to their value before the assembler sees the code.  The first token of each function is the function name.  The PI function returns the value of Pi times the (optional) parameter.  The RND function converts floating point to integer by rounding.  Yes, there is also a TRUNC function.  The V function returns the value of the argument.  That's how the fixed point value of Pi is ultimately moved into the assembler domain.

The above example was more verbose than needed to illustrate a few points.  It could have been:
<pre>
/const pifix integer = [rnd [pi 256]] ;create constant PIFIX

         mov     #[v pifix], w0 ;fixed point Pi into W0
</pre>

Or if the fixed point value of Pi is only used in this one place, it could have been:
<pre>
         mov     #[rnd [pi 256]], w0 ;fixed point Pi into W0
</pre>

ESCR is intended to allow applications (like PREPIC) to use it as a preprocessor and customize some of its features.  This could be done to create a C preprocessor.  C already reserves "#" for identifying preprocessor commands.  The hard part would be deciding the syntax for identifying preprocessor inline functions.  It would probably have to be a two-character sequence.  Another possibility is that an ESCR C preprocessor only produces specific #DEFINE C macros as its output, which are then handled in the usual way.  In other words, there wouldn't be any ESCR in-line functions except within ESCR preprocessor commands.