Result of bitwise OR operator in c - c

I have a question about bitwise OR | operator from c to rust.
I have this lot of define to convert from c to rust, and i’m not sure of the flag SEFLG_ASTROMETRIC.
#define SEFLG_JPLEPH 1 /* use JPL ephemeris */
#define SEFLG_SWIEPH 2 /* use SWISSEPH ephemeris */
#define SEFLG_MOSEPH 4 /* use Moshier ephemeris */
#define SEFLG_HELCTR 8 /* heliocentric position */
#define SEFLG_TRUEPOS 16 /* true/geometric position, not apparent position */
#define SEFLG_J2000 32 /* no precession, i.e. give J2000 equinox */
#define SEFLG_NONUT 64 /* no nutation, i.e. mean equinox of date */
#define SEFLG_SPEED3 128 /* speed from 3 positions (do not use it,
* SEFLG_SPEED is faster and more precise.) */
#define SEFLG_SPEED 256 /* high precision speed */
#define SEFLG_NOGDEFL 512 /* turn off gravitational deflection */
#define SEFLG_NOABERR 1024 /* turn off 'annual' aberration of light */
#define SEFLG_ASTROMETRIC (SEFLG_NOABERR|SEFLG_NOGDEFL) /* astrometric position,
* i.e. with light-time, but without aberration and
* light deflection */
#define SEFLG_EQUATORIAL (2*1024) /* equatorial positions are wanted */
#define SEFLG_XYZ (4*1024) /* cartesian, not polar, coordinates */
#define SEFLG_RADIANS (8*1024) /* coordinates in radians, not degrees */
#define SEFLG_BARYCTR (16*1024) /* barycentric position */
#define SEFLG_TOPOCTR (32*1024) /* topocentric position */
#define SEFLG_ORBEL_AA SEFLG_TOPOCTR /* used for Astronomical Almanac mode in
* calculation of Kepler elipses */
#define SEFLG_SIDEREAL (64*1024) /* sidereal position */
#define SEFLG_ICRS (128*1024) /* ICRS (DE406 reference frame) */
#define SEFLG_DPSIDEPS_1980 (256*1024) /* reproduce JPL Horizons
* 1962 - today to 0.002 arcsec. */
#define SEFLG_JPLHOR SEFLG_DPSIDEPS_1980
#define SEFLG_JPLHOR_APPROX (512*1024) /* approximate JPL Horizons 1962 - today */
1024 | 512
I tried with the calculator of my mac 1024 OR 512 and the result is 1536. Is this result correct ?

Yes, the result is correct: in fact, OR-ing 1024 and 512 yields the same number as adding them.
This is a convenient "shortcut" for OR-ing powers of two: since their digits never occupy the same position, addition is the same as "OR".
The same principle is in play here as with adding decimal numbers with zeros in all but a single position, when non-zero positions do not overlap: adding, say, 6000+900+30+7 is the same as writing down the individual digits into 6937, because place values do not interact with each other. OR-ing distinct powers of two in binary is the same as writing down all ones in positions designated by numbers being OR-ed.
Note that the expression (SEFLG_NOABERR|SEFLG_NOGDEFL) is evaluated at compile time, so replacing it with 1536 is not going to yield any run-time improvement.

In a word - yes. Note that 1024 and 512 don't have "1" bits in the same positions, so the result of bitwise-oring them is the same as adding them.

Yes it is correct.
512 =01000000000
1024=10000000000
1536=11000000000
OR-Calculation:
10000000000
|01000000000
=11000000000

Related

doxygen compact #define Documentation

I often have code like this:
#define limit_0 1.0f /**< Limit 0 */
#define limit_1 3.5 /**< Limit 1 */
#define limit_2 2 /**< Limit 2 */
and in this case the Doxygen HTML documentation ("Macro Definition Documentation") looks bad. A lot of overhead and a lot of lines.
I like the compact Enumerations documentation. For the example above I would like to have something like:
name
value
details
limit_0
1.0f
Limit 0
limit_1
3.5
Limit 1
limit_2
2
Limit 2
Is this possible?

Recursive audio solution

I just want to get my head wrapped around recursion using something simple. I want amplitudes from 1 to -1. This will take less than two minutes.
I just through together a recursive solution to practice recursing.
/* This program outputs amplitudes within a frequency of 440Hz.
The number of audio samples will add of up to 1024, and the highest frequency
We can generate is about 20KilHz.
*/
#include<stdio.h>
#include<math.h>
#define PI 3.141597
#define TwoPI (2*3.141597)
#define SampleRate 441000
#define Frequency 440
#define Buffer 1024
/* Recursively Generates Signal, it is called in main. */
/*int CalculateSignal(int Sampler){
Sampler=0;
int Sample= 0;
Sample=sin(Frequency*TwoPI*SampleRate);
printf("%.6f",Sample);
if(Sampler==Buffer){
return Sample;
}
else if(Sampler<Buffer){
return CalculateSignal(Sampler+1);
}
}*/
int main(){
CalculateSignal(1024);
}

ESP8266 hadrware timer, uS to ticks strange macro

Can someone explain me why this macro is written like this?!?...
Trying to understand how the ESP8266 hardware timer works, since manufacturer doesn't provide much data and their examples are just spagetti code.
Now a timer is a timer, just counts (down to 0 in ESP8266) based on it's HW clock and in this case is APB/4 or 20 MHz.
The uS to TICKS should be as simple as that:
ticks = uS * MHz
Now the Espressif examples shows a macro which basically do the same as above, depending on magic number 0x35A... ???
The magic path would be equivalent to:
ticks = uS/4 (no float, rounded dwn) * MHz * 4
+
us%4 * MHz
Why is that? Am I missing something?
Original one:
#define US_TO_RTC_TIMER_TICKS(t) \
((t) ? \
(((t) > 0x35A) ? \
(((t)>>2) * ((APB_CLK_FREQ>>4)/250000) + ((t)&0x3) * ((APB_CLK_FREQ>>4)/1000000)) : \
(((t) *(APB_CLK_FREQ>>4)) / 1000000)) : \
0)
Now breaking into it, it turns out that:
#define US_TO_RTC_TIMER_TICKS(t)
(
(t) ? ( // if t, ok for now
// hmmm... magic number for a timer 0x35A or 858 dec
((t) > 0x35A) ?
( // if greater than magic number
((t)>>2) * ((APB_CLK_FREQ>>4)/250000) + ((t)&0x3) * ((APB_CLK_FREQ>>4)/1000000)
// t/4[uS] * 80 equivalent with t * 20 but with match round
// Example
// 103uS normal would be 103uS * 20 = 2060 (as count)
//
// 103/4 = 25 * 80 = 2000 + 3 * 20 = 2000 + 60 = 2060
// hmmm.. correct but why?
) :
(
// if lower than MAGIC
// t / period = count <=> t[uS] * freq[MHz] = count
//
// t * 20 this is understandable :)
//
((t) *(APB_CLK_FREQ>>4)) / 1000000
)
) : 0
)
This is simply to prevent overflow. If the start value is greater than "not a magic number" then the multiplication with 'clock frequency / 4' can cause an overflow. To prevent this you can divide the number by four first (by bit-shifting so: '>> 2') but that would lose the resolution of the lower two bits because they would be lost. So the lower two bits are separated and then accounted for.
You can get the magic number by dividing the max value of an int by APB_CLK_FREQ >> 4 i.e.
(2 ^ 32 - 1) / ((80 * 10 ^ 6) / 16) = 858.99
We'll round off to a lower value so the max value we can handle directly is 858 or 0x35A.
I'd also like to correct you on the tics front. The hardware timer runs on the CPU frequency and the hw_timer source uses a prescaler of 16 though you can modify the source (with some effort - read the register definitions in the technical manual of esp8266) to use a prescaler of 1 or 256 too apart from 16.
So the tics per us would be
us * 80 * 10 ^ 6 / <pre-scaler>

How to log to /var/log/mail.log using rsyslogd?

I am currently playing around with logging under Linux. I have made the following very simple test application (in plain C):
#include <syslog.h>
int main(int argc, char **argv)
{
openlog("mytest", (LOG_PID | LOG_NDELAY), LOG_MAIL);
syslog(LOG_MAKEPRI(LOG_MAIL, LOG_ERR), "Test");
return(0);
}
This "application" compiles, and when I execute it, it generates an entry in /var/log/syslog, but no entry in /var/log/mail.log and no entry in /var/log/mail.err.
Could somebody please explain why?
I am using rsyslogd on the test machine; this is the configuration from /etc/rsyslog.conf (please note that /etc/rsyslog.d is just empty, and that I have stripped out all comments and lines which clearly don't have anything to do with the problem):
:msg,startswith, " fetching user_deny" ~
:msg,startswith, " seen_db: user " ~
auth,authpriv.* /var/log/auth.log
*.*;auth,authpriv.none -/var/log/syslog
daemon.* -/var/log/daemon.log
kern.* -/var/log/kern.log
lpr.* -/var/log/lpr.log
mail.* -/var/log/mail.log
user.* -/var/log/user.log
mail.info -/var/log/mail.info
mail.warn -/var/log/mail.warn
mail.err /var/log/mail.err
*.=debug;\
auth,authpriv.none;\
news.none;mail.none -/var/log/debug
*.=info;*.=notice;*.=warn;\
auth,authpriv.none;\
cron,daemon.none;\
mail,news.none -/var/log/messages
*.emerg :omusrmsg:*
daemon.*;mail.*;\
news.err;\
*.=debug;*.=info;\
*.=notice;*.=warn |/dev/xconsole
As far as I have understood from reading man rsyslog.conf, that configuration should make rsyslogd write messages for LOG_MAIL with priority LOG_ERR to /var/log/mail.err. I am somewhat mistrustful regarding the lines where the file path has a - prepended, though. I don't know what this means because I could not find any hint in the manual.
So what is going wrong?
I hate answering my own question, but I think I have found a bug either in the documentation or in the source of glibc, and I'd like to have it documented for future visitors of this question.
From https://www.gnu.org/software/libc/manual/html_node/syslog_003b-vsyslog.html#syslog_003b-vsyslog (as per the time of this writing):
syslog submits the message with the facility and priority indicated by
facility_priority. The macro LOG_MAKEPRI generates a facility/priority
from a facility and a priority, as in the following example:
LOG_MAKEPRI(LOG_USER, LOG_WARNING)
Now look at some code from syslog.h as it resides on my test machine (Debian wheezy, up-to-date, no custom patches, non-relevant parts stripped out):
/*
* priorities/facilities are encoded into a single 32-bit quantity, where the
* bottom 3 bits are the priority (0-7) and the top 28 bits are the facility
* (0-big number). Both the priorities and the facilities map roughly
* one-to-one to strings in the syslogd(8) source code. This mapping is
* included in this file.
*
* priorities (these are ordered)
*/
#define LOG_EMERG 0 /* system is unusable */
#define LOG_ALERT 1 /* action must be taken immediately */
#define LOG_CRIT 2 /* critical conditions */
#define LOG_ERR 3 /* error conditions */
#define LOG_WARNING 4 /* warning conditions */
#define LOG_NOTICE 5 /* normal but significant condition */
#define LOG_INFO 6 /* informational */
#define LOG_DEBUG 7 /* debug-level messages */
#define LOG_MAKEPRI(fac, pri) (((fac) << 3) | (pri))
/* facility codes */
#define LOG_KERN (0<<3) /* kernel messages */
#define LOG_USER (1<<3) /* random user-level messages */
#define LOG_MAIL (2<<3) /* mail system */
#define LOG_DAEMON (3<<3) /* system daemons */
#define LOG_AUTH (4<<3) /* security/authorization messages */
#define LOG_SYSLOG (5<<3) /* messages generated internally by syslogd */
#define LOG_LPR (6<<3) /* line printer subsystem */
#define LOG_NEWS (7<<3) /* network news subsystem */
#define LOG_UUCP (8<<3) /* UUCP subsystem */
#define LOG_CRON (9<<3) /* clock daemon */
#define LOG_AUTHPRIV (10<<3) /* security/authorization messages (private) */
#define LOG_FTP (11<<3) /* ftp daemon */
/* other codes through 15 reserved for system use */
#define LOG_LOCAL0 (16<<3) /* reserved for local use */
#define LOG_LOCAL1 (17<<3) /* reserved for local use */
#define LOG_LOCAL2 (18<<3) /* reserved for local use */
#define LOG_LOCAL3 (19<<3) /* reserved for local use */
#define LOG_LOCAL4 (20<<3) /* reserved for local use */
#define LOG_LOCAL5 (21<<3) /* reserved for local use */
#define LOG_LOCAL6 (22<<3) /* reserved for local use */
#define LOG_LOCAL7 (23<<3) /* reserved for local use */
We are obviously having multiple problems here.
The comment at the top: If I have 3 bottom bits, then I have 29 top bits (and not 28). But this is a minor problem.
The facility codes are already defined as shifted-to-left by three bits. Using the macro LOG_MAKEPRI (as recommended by the manual page linked above) obviously shifts them to the left by three bits a second time, which clearly is wrong.
SOLUTION
The solution is simple: Don't use that macro; instead, just OR the facility code and the priority code. I have tried that, and it worked. Error messages from my test programs are now logged as expected, according to the configuration of rsyslogd in /etc/rsyslog.conf.
I am quite surprised about that very obvious bug in syslog.h ...

Hooking mmap system to provide real-time type conversion?

I'm working on some stuff where I want to memory map some large files containing numeric data. The problem is that the data can be a number of formats, including real byte/short/int/long/float/double and complex byte/short/int/long/float/double. Naturally handling all those types all the time quickly gets unwieldy, so I was thinking of implementing a memory mapping interface that can do real-time type conversion for the user.
I really like the idea of mapping a file so you get a pointer in memory back, doing whatever you need and then unmapping it. No bufferology or anything else needed. So a function that reads the data and does the type conversion for me would take a lot away from that.
I was thinking I could memory map the file being operated on, and then simultaneously mapping an anonymous file, and somehow catching page fetches/stores and doing the type conversion on demand. I'll be working on 64-bit so this would give you a 63-bit address space in these cases, but oh well.
Does anyone know if this sort of mmap hooking would be possible, and if so, how might it be accomplished?
Yes(-ish). You can create inaccessible mmap regions. Whenever anybody tries to touch one, handle the SIGSEGV raised by fixing its permissions, filling it, and resuming.
long *long_view =
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
double *double_view =
mmap(NULL, 4096, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
static void on_segv(int signum, siginfo_t *info, void *data) {
void *addr = info->si_addr;
if ((uintptr_t)addr - (uintptr_t)long_view < 4096) {
mprotect(long_view, 4096, PROT_READ|PROT_WRITE);
/* translate from double_view to long_view */
mprotect(double_view, 4096, PROT_NONE);
} else if ((uintptr_t)addr - (uintptr_t)double_view < 4096) {
mprotect(double_view, 4096, PROT_READ|PROT_WRITE);
/* translate from long_view to long_view */
mprotect(double_view, 4096, PROT_NONE);
} else {
abort();
}
}
struct sigaction segv_action = {
.sa_sigaction = on_segv,
.sa_flags = SA_RESTART | SA_SIGINFO,
};
sigaction(SIGSEGV, &segv_action, NULL);
long_view[0] = 42;
/* hopefully, this will trigger the code to fixup double_view and resume */
printf("%g\n", double_view[0]);
(Untested, but something along these lines ought to work...)
If you don't want to fill a whole page at once, that's still doable I think... the third argument can be cast to a ucontext_t *, with which you can decode the instruction being executed and fix it up as if it had performed the expected operation, while leaving the memorry PROT_NONE to catch further accesses... but it'll be a lot slower since you're trapping every access rather than just the first.
The reading part sounds somewhat doable to me. I have no experience in that, but in principle having a signal handler fetch your data and translate it as soon as you access a page that is not yet present in your user-presented buffer should be possible. But it could be that such a thing would be quite inefficient, you'd have a context switch on every page.
The other way round would be much harder I guess. Per default writes are asynchronous, so it will be difficult to capture them.
So "half" of what you want could be possible: always write the data in a new file in the format that the user wants, but translate it automatically on the fly when reading such a file.
But what would be much more important for you, I think, that you have a clear semantic on your different storage representation, and that you encapsulate a read or write of a data item properly. If you have such an interface (something like "store element E at position i with type T") you could easily trigger the conversion with respect to the target format.
Is there a reason why you're not using accessor functions?
There are two basic cases: structured data, and plain data. Structured data has mixed data types, plain data only one format of the ones you listed. You could also have support for transparent endianness correction, if you can store a prototype value (with distinct byte components) for each used type (28 or 30 bytes total for all types you listed -- complex types are just pairs, and have the same byte order as the base components). I have used this approach to store and access atom data from molecular dynamics simulations, and is quite efficient in practice -- the fastest portable one I've tested.
I would use a structure to describe the "file" (the backing file, memory map, endianness, and data format if plain data):
struct file {
int descriptor;
size_t size;
unsigned char *data;
unsigned int endian; /* Relative to current architecture */
unsigned int format; /* endian | format, for unstructured files */
};
#define ENDIAN_I16_MASK 0x0001
#define ENDIAN_I16_12 0x0000
#define ENDIAN_I16_21 0x0001
#define ENDIAN_I32_MASK 0x0006
#define ENDIAN_I32_1234 0x0000
#define ENDIAN_I32_4321 0x0002
#define ENDIAN_I32_2143 0x0004
#define ENDIAN_I32_3412 0x0006
#define ENDIAN_I64_MASK 0x0018
#define ENDIAN_I64_1234 0x0000
#define ENDIAN_I64_4321 0x0008
#define ENDIAN_I64_2143 0x0010
#define ENDIAN_I64_3412 0x0018
#define ENDIAN_F16_MASK 0x0020
#define ENDIAN_F16_12 0x0000
#define ENDIAN_F16_21 0x0020
#define ENDIAN_F32_MASK 0x00C0
#define ENDIAN_F32_1234 0x0000
#define ENDIAN_F32_4321 0x0040
#define ENDIAN_F32_2143 0x0080
#define ENDIAN_F32_3412 0x00C0
#define ENDIAN_F64_MASK 0x0300
#define ENDIAN_F64_1234 0x0000
#define ENDIAN_F64_4321 0x0100
#define ENDIAN_F64_2143 0x0200
#define ENDIAN_F64_3412 0x0300
#define FORMAT_MASK 0xF000
#define FORMAT_I8 0x1000
#define FORMAT_I16 0x2000
#define FORMAT_I32 0x3000
#define FORMAT_I64 0x4000
#define FORMAT_P8 0x5000 /* I8 pair ("complex I8") */
#define FORMAT_P16 0x6000 /* I16 pair ("complex I16") */
#define FORMAT_P32 0x7000 /* I32 pair ("complex I32") */
#define FORMAT_P64 0x8000 /* I64 pair ("complex I64") */
#define FORMAT_R16 0x9000 /* BINARY16 IEEE-754 floating-point */
#define FORMAT_R32 0xA000 /* BINARY32 IEEE-754 floating-point */
#define FORMAT_R64 0xB000 /* BINARY64 IEEE-754 floating-point */
#define FORMAT_C16 0xC000 /* BINARY16 IEEE-754 complex */
#define FORMAT_C32 0xD000 /* BINARY32 IEEE-754 complex */
#define FORMAT_C64 0xE000 /* BINARY64 IEEE-754 complex */
The accessor functions can be implemented in various ways. In Linux, functions marked static inline are as fast as macros, too.
Since the double type does not fully cover 64-bit integer types (since it has only 52 bits in the mantissa), I'd define a number structure,
#include <stdint.h>
struct number {
int64_t ireal;
int64_t iimag;
double freal;
double fimag;
};
and have the accessor functions always fill in the four fields. Using GCC, you can also create a macro to define a struct number using automatic type detection:
#define Number(x) \
( __builtin_types_compatible_p(__typeof__ (x), double) ? number_double(x) : \
__builtin_types_compatible_p(__typeof__ (x), _Complex double) ? number_complex_double(x) : \
__builtin_types_compatible_p(__typeof__ (x), _Complex long) ? number_complex_long(x) : \
number_int64(x) )
static inline struct number number_int64(const int64_t x)
{
return (struct number){ .ireal = (int64_t)x,
.iimag = 0,
.freal = (double)x,
.fimag = 0.0 };
}
static inline struct number number_double(const double x)
{
return (struct number){ .ireal = (int64_t)x,
.iimag = 0,
.freal = x,
.fimag = 0.0 };
}
static inline struct number number_complex_long(const _Complex long x)
{
return (struct number){ .ireal = (int64_t)(__real__ (x)),
.iimag = (int64_t)(__imag__ (x)),
.freal = (double)(__real__ (x)),
.fimag = (double)(__imag__ (x)) };
}
static inline struct number number_complex_double(const _Complex double x)
{
return (struct number){ .ireal = (int64_t)(__real__ (x)),
.iimag = (int64_t)(__imag__ (x)),
.freal = __real__ (x),
.fimag = __imag__ (x) };
}
This means that Number(value) constructs a correct struct number as long as value is an integer or floating-point real or complex type.
Note how the integer and floating-point components are set to the same values, as far as type conversions allow. (For very large integers in magnitude, the floating-point value will be an approximation. You could also use (int64_t)round(...) to round instead of truncate the floating-point parameter, when setting the integer component(s).
You'll need four accessor functions: Two for structured data, and two for unstructured data. For unstructured (plain) data:
static inline struct number file_get_number(const struct file *const file,
const size_t offset)
{
...
}
static inline void file_set_number(const struct file *const file,
const size_t offset,
const struct number number)
{
...
}
Note that offset above is not the byte offset, but the index of the number. For a structured file, you'll need to use the byte offset, and add a parameter specifying the number format used in the file:
static inline struct number file_get(const struct file *const file,
const size_t byteoffset,
const unsigned int format)
{
...
}
static inline void file_set(const struct file *const file,
const size_t byteoffset,
const unsigned int format,
const struct number number)
{
...
}
The conversions needed in the function bodies I omitted (...) are quite straightforward. There are a few tricks you can do for optimization, too. For example, I like to adjust the endianness constants so that the low bit is always a byte swap (ab -> ba, abcd -> badc, abcdefgh -> badcfehg), and the high bit is a short swap (abcd -> cdab, abcdefgh ->cdabghef). You might need a third bit for 64-bit values (abcdefgh -> efghabcd), if you want to be completely certain.
The if or case statements within the function body do cause a small access overhead, but it should be small enough to ignore in practice. All ways to avoid it will lead to much more complex code. (For maximum throughput, you'd need to open-code all access variants, and use __builtin_types_compatible_p() in a function or macro to determine the correct one to use. If you consider the endianness conversion, that means quite a few functions. I believe the very small access overhead -- a few clocks at most per access -- is much more preferable. (All my tests have been I/O bound anyway, even at 200 Mb/s, so to me the overhead is completely irrelevant.)
In general, for automatic endianness conversion using prototype values you simply test each possible conversion for the type. As long as each byte component of the prototype values are unique, then only one conversion will produce the correct expected value. On some architectures integers and floating-point values have different endianness; this is why the ENDIAN_ constants are for each type and size separately.
Assuming you have implemented all of the above, in your application code the data access would look something like
struct file f;
/* Set first number to zero. */
file_set_number(&f, 0, Number(0));
/* Set second number according to variable v,
* which can be just about any numeric type. */
file_set_number(&f, 1, Number(v));
I hope you find this useful.

Resources