100mm to twips in LibreOffice - c++

I have been reading some of the LibreOffice code, and there is code that converts from 100mm to twips.
Its basic formula is:
twips = (n>=0) ? (n*72+63) / 127 : (n*72-63) / 127;
Now I know that one twip is 1/20th of a point, and that one inch is 72 points, and 1 inch is 2.54cm, but I cannot work out how the above formula relates to these ratios!
Can anyone shed some light on this?

Putting together what OP provided:
n is the size in 100 mm.
1 inch is 2.54 cm is 25.4 mm.
inchs = n * 100 / 25.4
or inchs = n / (100 * 25.4)
or inchs = n / 2540
1 inch is 72 points.
points = inchs * 72
1 twip is 1/20th point.
twips = points / 20
Now, everything together:
twips = n / 2540 * 72 / 20
or twips = n * 72 / 2540 / 20
or twips = n * 72 / 127
If this is done in int arithmetic there will be truncation instead of mathematical rounding. This can be fixed by adding the half of 127 (127 / 2 = 63) to n * 72:
twips = (n * 72 + 63) / 127
This does not handle negative numbers correctly. For these, the 63 has to be subtracted instead:
twips = n >= 0 ? (n * 72 + 63) / 127) : (n * 72 - 63) / 127;
and here we are.
As already pointed out by Ron, the ?: operator is the ternary if-then-else operator.
An easier to read (but may be less optimized) replacement would be:
if (n >= 0) twips = (n * 72 + 63) / 127);
else twips = (n * 72 - 63) / 127;

Related

I need to transfer data from GPS module to char[ ] in Arduino IDE. The question is what is ( / 10 + 48; ) or (/ 10) % 10 + 48;) How this used for?

Please, name thise methods.I new there, could you provide some reference?
char Time[] = "TIME:00:00:00";
void loop() {
Date[5] = gps.date.day() / 10 + 48;
Date[6] = gps.date.day() % 10 + 48;
Date[8] = gps.date.month() / 10 + 48; //Please, name thise methods.
Date[9] = gps.date.month() % 10 + 48;
Date[13] =(gps.date.year() / 10) % 10 + 48;
Date[14] = gps.date.year() % 10 + 48;}
Adding 48 is a way to convert a digit to a corresponding character. ASCII codes of digits start with 48 for '0'. so 5 + '0' is '5'.
x / 10 is division of x by 10. with integer division you get 2 from 23
x % 10 is modulo of x by 10. you get the remainder of division of x by 10. so you get 3 from 23.
So the code in question converts time digit by digit to a printable text.

Debugging old Fortran code for sediment dynamics

I am looking at some Fortran code from an old scanned paper. The scan quality is not great so I may have copied it wrong. I tried to run this using an online Fortran compiler but it bombs out. Not being familiar with Fortran, I was wondering if someone can point out where the syntax does not make sense? The code is from a paper on sediment dynamics:
Komar, P.D. and Miller, M.C., 1975. On the comparison between the threshold of sediment motion under waves and unidirectional currents with a discussion of the practical evaluation of the threshold: Reply. Journal of Sedimentary Research, 45(1).
PROGRAM TSHOLD
REAL LI, LO
G = 981.0
PIE = 3.1416
RHOW = 1.00
READ (6O,1) DIAM, RHOS
1 FORMAT (2X, F6.3,2X, F5.3)
IF(DIAM .LT. 0.05) GO TO 5
A = 0.463 * PIE
B = 0.25
GO TO 7
5 A = 0.21
B = 0.50
7 PWR = 1.0 / (2.0 - B)
FAC = (A * (RHOS - RHOW) * G/(RHOW * PIE**B))**PWR
FAC1 = FAC * DIAM**((1.0 - B) * PWR)
T = 1.0
15 J = 1.20
LD = 156.13 * (T**2)
UM = FAC1 * T**(B*PWR)
WRITE(61,9) DIAM, T, UM
9 FORMAT(1H0, 10X, 17HGRAIN DIAMETER = ,F6.3,1X,2HCM //
1 11X, 14HWAVE PERIOD = ,F5.2, 1X, 3HSEC //
2 11X, 22HORBITAL VELOCITY, UM = ,F6.2, 1X, 6HCM/SECl //
3 20X, 6HHEIGHT, 5X, 5HDEPTH, 8X, 3HH/L, 6X, 7HH/DEPTH //
4 22X, 2HCM, 8X, 2HCM /)
C INCREMENT WAVE HEIGHT, CALCULATE DEPTH
H = 10.0
DO 12 K = 1.60
SING = PIE * H / (UM * T)
X = SING
IF(X.LT.1.0) GO TO 30
30 ASINH = X - 0.16666*X**3.0 + 0.07500* X ** 5.0 - 0.04464 * X ** 7.0
1 + 0.03038 * X ** 9.0 - 0.02237 * X ** 11.0
32 LI = LD * (SINH(ASINH)/COSH(ASINH))
OPTH = ASINH * LI / 6.2832
C CHECK WAVE STABILITY
RATIO = H / DPTH
IF(RATIO.GE.0.78) GO TO 11
STEEP = H / LI
TEST = 0.142 * (SINH(ASINH)/COSH(ASINH))
IF(STEEP.GE.TEST) GO TO 11
WRITE(61,10) H, OPTH, STEEP, RATIO
I0 FORMAT(IH0, 20X, F5.1, 4X, E9.3, 4X, F5.3, 4X, F4.2)
11 H = H + 10.0
12 CONTINUE
T = T + 1.0
15 CONTINUE
END
The problem is more likely that old Fortran requires fixed form code formatting where the number of spaces before a statement is very important.
Here are some general rules
Normal statements start at column 7 and beyond
Lines cannot exceed 72 columns
Any character placed on column 6 indicates the line is a continuation from the line above. I see that on the code above in the lines following 9 FORMAT(..
A number placed between columns 1-5 indicates a label, which can be a target of a GO TO statement, a DO statement or a formatting specification.
The character C on the first column, and sometimes any character on the first column indicate the line is a comment line.
see https://people.cs.vt.edu/~asandu/Courses/MTU/CS2911/fortran_notes/node4.html for more info.
Based on the rules above, here is how to enter the code, with the correct spacing. I run the F77 code through a converter to make it compatible with F90 and F77 at the same time. The code below might compile with the online compiler now.
PROGRAM TSHOLD
REAL LI, LO
G = 981.0
PIE = 3.1416
RHOW = 1.00
READ (60,1) DIAM, RHOS
1 FORMAT (2X, F6.3,2X, F5.3)
IF(DIAM .LT. 0.05) GO TO 5
A = 0.463 * PIE
B = 0.25
GO TO 7
5 A = 0.21
B = 0.50
7 PWR = 1.0 / (2.0 - B)
FAC = (A * (RHOS - RHOW) * G/(RHOW * PIE**B))**PWR
FAC1 = FAC * DIAM**((1.0 - B) * PWR)
T = 1.0
DO 15 J=1,20
LD = 156.13 * (T**2)
UM = FAC1 * T**(B*PWR)
WRITE(61,9) DIAM, T, UM
9 FORMAT(1H0, 10X, 17HGRAIN DIAMETER = ,F6.3,1X,2HCM // &
& 11X, 14HWAVE PERIOD = ,F5.2, 1X, 3HSEC // &
& 11X, 22HORBITAL VELOCITY, UM = ,F6.2, 1X, 6HCM/SECl // &
& 20X, 6HHEIGHT, 5X, 5HDEPTH, 8X, 3HH/L, 6X, 7HH/DEPTH // &
& 22X, 2HCM, 8X, 2HCM /)
! INCREMENT WAVE HEIGHT, CALCULATE DEPTH
H = 10.0
DO 12 K = 1,60
SING = PIE * H / (UM * T)
X = SING
IF(X.LT.1.0) GO TO 30
30 ASINH = X - 0.16666*X**3.0 + 0.07500* X ** 5.0 - 0.04464 * X ** 7.&
& + 0.03038 * X ** 9.0 - 0.02237 * X ** 11.0
32 LI = LD * (SINH(ASINH)/COSH(ASINH))
OPTH = ASINH * LI / 6.2832
! CHECK WAVE STABILITY
RATIO = H / DPTH
IF(RATIO.GE.0.78) GO TO 11
STEEP = H / LI
TEST = 0.142 * (SINH(ASINH)/COSH(ASINH))
IF(STEEP.GE.TEST) GO TO 11
WRITE(61,10) H, OPTH, STEEP, RATIO
10 FORMAT(G14.4, 20X, F5.1, 4X, E9.3, 4X, F5.3, 4X, F4.2)
11 H = H + 10.0
12 CONTINUE
T = T + 1.0
15 CONTINUE
END
I found several transcription errors, replacing commas with dots, zeros with the letter O, and a missing DO statement.

Why do these RNG's in C++ and R not produce similar results?

Please excuse the disgustingly noobish nature of this post, but I have a question for those who program in C++ and R on their personal computer.
Question: Why are these random numbers produced from the two programs below not equal, and how do I resolve this issue?
Firstly, I suspect that I have misused the local function and the <<- operator in the R program.
Secondly, I suspect it may be a floating-accuracy issue. It's not immediately obvious to me how the two programs are different, so I don't know how to go about this problem.
I have tried casting all my calculations in C++ to double/float (even long double), and using fmod instead of the modulus operator %: different outputs again, but still not similar to the output in R. I do not know if it of any significant importance, but I want to add that I am compiling the C++ code using the G++ compiler.
Algorithm: The following algorithm can be used in any standard personal computer. It was proposed to use in parallel three word generators,
mk = 171 mk-1 (mod 30269)
m'k = 172 m'k-1 (mod 30307)
m''k = 172 m''k-1 (mod 30323)
and to use as pseudorandom numbers the fractional parts
gk = {mk / 30269 + m'k / 30307 + m''k / 30323}
I have used the initial values m0 = 5, m'0 = 11, and m''0 = 17.
Programs: I have the following program in C++:
//: MC:Uniform.cpp
// Generate pseudo random numbers uniformly between 0 and 1
#include <iostream>
#include <math.h> // For using "fmod()"
using namespace std;
float uniform(){
// A sequence of initial values
static int x = 5;
static int y = 11;
static int z = 17;
// Some integer arithmetic required
x = 171 * (x % 177) - 2 * (x / 177);
y = 172 * (x % 176) - 35 * (y / 176);
z = 170 * (x % 178) - 63 * (z / 178);
/* If both operands are nonnegative then the
remainder is nonnegative; if not, the sign of
the remainder is implementation-defined. */
if(x < 0)
x = x + 30269;
if(y < 0)
y = y + 30307;
if(z < 0)
z = z + 30323;
return fmod(x / 30269. + y / 30307. + z / 30323., 1.);
}
int main(){
// Print 5 random numbers
for(int i = 0; i < 5; i++){
cout << uniform() << ", ";
}
}///:~
The program exites with code and outputs the following:
0.686912, 0.329174, 0.689649, 0.753722, 0.209394,
I also have a program in R, that looks like the following:
## Generate pseudo random numbers uniformly between 0 and 1
uniform <- local({
# A sequence of initial values
x = 5
y = 11
z = 17
# Use the <<- operator to make x, y and z local static
# variables in R.
f <- function(){
x <<- 171 * (x %% 177) - 2 * (x / 177)
y <<- 172 * (y %% 176) - 35 * (y / 176)
z <<- 170 * (z %% 178) - 63 * (z / 178)
return((x / 30269. + y / 30307. + z / 30323.)%%1.)
}
})
# Print 5 random numbers
for(i in 1:5){
print(uniform())
}
This program exites with code as well and produces the output
[1] 0.1857093
[1] 0.7222047
[1] 0.05103441
[1] 0.7375034
[1] 0.2065817
Any suggestions are appreciated, thanks in advance.
You need a few more %/%'s (integer division) in your R code. Remember that numeric variables in R are floating-point, not integer, by default; so / will do ordinary division with a non-integral quotient. You've also left out the part where you deal with negative x/y/z.
f <- function(){
x <<- 171 * (x %% 177) - 2 * (x %/% 177)
y <<- 172 * (y %% 176) - 35 * (y %/% 176)
z <<- 170 * (z %% 178) - 63 * (z %/% 178)
if(x < 0)
x <<- x + 30269;
if(y < 0)
y <<- y + 30307;
if(z < 0)
z <<- z + 30323;
return((x / 30269. + y / 30307. + z / 30323.)%%1)
}
After making those changes, there doesn't seem to be anything seriously wrong with the result. A quick histogram of 100000 random draws looks very uniform, and there's no autocorrelation I can find. Still doesn't match your C++ result though....
There's a simple copy/paste error in your C++ code. This
x = 171 * (x % 177) - 2 * (x / 177);
y = 172 * (x % 176) - 35 * (y / 176);
z = 170 * (x % 178) - 63 * (z / 178);
should be this.
x = 171 * (x % 177) - 2 * (x / 177);
y = 172 * (y % 176) - 35 * (y / 176);
z = 170 * (z % 178) - 63 * (z / 178);

Recursion in c++

I got an exam two days from now and my professor gave us an old exam with the solutions however after going over this problem countless of times I can't figure out how in the world the answer is the answer.
int recursive (int n) {
if (n < 10) return n;
return 100 * recursive (n / 100) + 10 * (n % 10);
}
int main(){
cout << recursive (19683) << endl;
return 0;
}
The answer should print out 16030 but I have no idea of how it gets that. I do
100*196+10*3 = 19630
Then I do
100*1+10*3 = 130
which is completely wrong would appreciate it if someone knew how to get to that answer
The first call (recursive(19683)) returns:
100 * recursive(196) + 10*3
The second call (recursive(196)) returns:
100 * recursive(1) + 10*6
The third call (recursive(1)) returns 1 directly. Substituting back, one gets:
100 * (100 * 1 + 60) + 30 = 10000 + 6000 + 30 = 16030
Back in high school we were taught to be able to desk check our code. Desk checking is where you compute, by hand, the result of every step.
int recursive (int n) {
if (n < 10) return n;
return 100 * recursive (n / 100) + 10 * (n % 10);
}
Pass this 19683
recursive(19683)
19683 < 10 is false
return 100 * recursive(196) + 10 * (19683 % 10 -> 3)
recursive(196)
196 < 10 is false
return 100 * recursive(1) + 10 * (196 % 10 -> 6)
recursive(1)
1 < 10 is true, return 1
substitute recursive(1) = 1 into earlier equation...
return 100 * 1 * 60 -> 160
substitute recursive(196) = 160 into earlier equation...
return 100 * 160 + 10 * 3 -> 16030
recursive(19683) = 100 * recursive(196) + 10 * 3
recursive(196) = 100 * recursive(1) + 10 * 6
recursive(1) = 1
Now back-fill the answers
recursive(196) = 100 + 60
recursive(19683) = 100 * 160 + 30 = 16030
In order to understand what's happening, look at a a simpler example of recursion, such as reversing a string. There's a good explanation of how recursion works in the answers to this question: -
Reverse a string using recursion
Once that makes sense to you, you should find understanding the example question you pose much easier.

Permutation of a number's digits

Consider number 194 declared as type int
Is it possible to obtain it's digits permutations like other ints efficiently?
Number: 194
419 int
491 int
914 int
941 int
I am using the next_permutation however it only works with arrays. So I thought it wouldn't be wise to convert int to an int array (?!) then obtain the permutation as an array and convert it to it.
Any suggestions?
Permuting the digits is basically a string-operation, not a (simple) mathematical operation. Converting to an array (string) and then using next_permutation() sounds more sensible than trying to do it mathematically.
Here's the mathematical version - without intermediate values saved:
int a = 194;
int b = (a / 100) * 100 + (a % 10) * 10 + ((a / 10) % 10) * 1; // 149
int c = (a % 10) * 100 + ((a / 10) % 10) * 10 + (a / 100) * 1; // 491
int d = (a % 10) * 100 + (a / 100) * 10 + ((a / 10) % 10) * 1; // 419
int e = ((a / 10) % 10) * 100 + (a / 100) * 10 + (a % 10) * 1; // 914
int f = ((a / 10) % 10) * 100 + (a % 10) * 10 + (a / 100) * 1; // 941
With intermediate values, it's a little easier to see what's going on (except that I generated different assignments for b through f this time).
int a = 194;
int d1 = a / 100;
int d2 = (a / 10) % 10;
int d3 = a % 10;
int a = d1 * 100 + d2 * 10 + d3 * 1; // 194
int b = d1 * 100 + d3 * 10 + d2 * 1; // 149
int c = d2 * 100 + d1 * 10 + d3 * 1; // 914
int d = d2 * 100 + d3 * 10 + d1 * 1; // 941
int e = d3 * 100 + d1 * 10 + d2 * 1; // 419
int f = d3 * 100 + d2 * 10 + d1 * 1; // 491
Use the next_permutation() mechanism; it will generalize to 4-digit and 5-digit and N-digit numbers where this will not.
You'd first have to extract each decimal place's value first: either by converting it to a character array (itoa()) or by writing a small for loop that divides the number by powers of 10. Once you have the digits separated, you can write a loop to generate the permutations.
Getting the permutations of the decimal digits will require you to interact with the number as a decimal, so power-of-2 manipulations are probably not going to help much here.
My suggestion would be:
1. Convert number to string
2. Set up the string as a circular buffer
3. Step through the buffer progressively (each increment of the index into the circular buffer will give you one permutation)
4. Reconstruct the number from the "new" arrangement of the characters representing the digits
5. Repeat for the length of the string.
Unless you are running in a slow/resource-constrained environment, I wouldn't try to overthink the problem beyond this.
Edit:
As pointed out in the comments this doesn't generate all permutations, to do so would require adding another step at the end where the process is repeated but with progressively larger increments to the index variable.