gavinhoward / bc

An implementation of the POSIX bc calculator with GNU extensions and dc, moved away from GitHub. Finished, but well-maintained.
https://git.gavinhoward.com/gavin/bc
Other
145 stars 29 forks source link

Fractional power support? #37

Closed depler closed 2 years ago

depler commented 2 years ago

Why there is still no fractional power support and some other useful functions?

gavinhoward commented 2 years ago

There is. It is the function p(x, y) in the Extended Math Library. x is the base, and y is the power.

There are also a lot of useful functions in the Extended Math Library, in fact, but you have to use the -l command-line option to use them, like so:

bc -l

However, the p(x, y) function may not exist in the version you have. That particular function was added in version 2.6.0.

If you are running the version in either busybox or toybox, they are very old and do not have that function.

Can you send me the output of bc --version, please?

depler commented 2 years ago

Yep, I am using busybox version:

bc 1.34.0-FRP-4264-gc79f13025
Adapted from https://github.com/gavinhoward/bc
Original code (c) 2018 Gavin D. Howard and contributors

I've just tried latest version 5.0.1 and p(x,y) is working fine, except for precision loss: pow(32, 0.2) calculates 1.999999... instead of 2 - that is a little bit sad.

Anyway, is there any windows binary with static linkage? And why release version contains dependency for debug version of VCRUNTIME140D.dll?

image

gavinhoward commented 2 years ago

I've just tried latest version 5.0.1 and p(x,y) is working fine, except for precision loss: pow(32, 0.2) calculates 1.999999... instead of 2 - that is a little bit sad.

That's because of the nature of the formula required to calculate fractional powers. It uses transcendental functions, which cannot calculate precise values; they will almost always be off by one "unit in the last place" (ulp).

A lot of calculators do a trick behind the scenes where they round the result for you, but the bc standard requires that bc does not do that. Specifically, this quote:

Internal computations shall be conducted as if in decimal, regardless of the input and output bases, to the specified number of decimal digits. When an exact result is not achieved (for example, scale=0; 3.2/1), the result shall be truncated.

Because the standard requires that answers are truncated and not rounded, my bc will not round answers for you.

However, another function in the Extended Math Library will round for you. It's r(x, p). x is the number to round, and p is the number of decimal places to round to. So you can use it like so:

r(p(32, 0.2), 10)

and it will return 2.0000000000 (2 rounded to 10 decimal places).

Anyway, is there any windows binary with static linkage? And why release version contains dependency for debug version of VCRUNTIME140D.dll?

I do not know why it pulls in the debug version.

I am not a Windows programmer, actually, and I have to make a special effort to make my bc work on Windows. I stopped working on it once bc worked on Windows, so there's probably something about the build that is less than ideal.

As for static linking, I did not know that was even possible on Windows.

If you could help me figure out what I need to do to get both of those things better, I would appreciate it, but I'm just too inexperienced with Windows to do it alone.

depler commented 2 years ago

I do not know why it pulls in the debug version.

I am not a Windows programmer, actually, and I have to make a special effort to make my bc work on Windows. I stopped working on it once bc worked on Windows, so there's probably something about the build that is less than ideal.

As for static linking, I did not know that was even possible on Windows.

If you could help me figure out what I need to do to get both of those things better, I would appreciate it, but I'm just too inexperienced with Windows to do it alone.

Ok, it seems release configuration is totally broken in project bc.vcxproj, because it has equal settings from debug configuration. It means that by fact you released Debug configuration with slow code execution. I would rather create new solution from scratch to be sure that all setting are correct. A little bit confused of compiler definitions:

BC_ENABLED=1
DC_ENABLED=1
BC_ENABLE_EXTRA_MATH=1
BC_ENABLE_HISTORY=1
BC_ENABLE_NLS=0
BC_DEBUG_CODE=0
BC_ENABLE_LIBRARY=0
EXECSUFFIX=.exe
BUILD_TYPE=N
BC_DEFAULT_BANNER=1
BC_DEFAULT_SIGINT_RESET=0
DC_DEFAULT_SIGINT_RESET=0
BC_DEFAULT_TTY_MODE=1
DC_DEFAULT_TTY_MODE=1
BC_DEFAULT_PROMPT=1
DC_DEFAULT_PROMPT=1

Is that all correct? Also, strgen custom build for internal scripts and help text is unexpected to see 😊 I'll try to create pull request to fix things a little bit later, if you don't mind

gavinhoward commented 2 years ago

Ok, it seems release configuration is totally broken in project bc.vcxproj, because it has equal settings from debug configuration. It means that by fact you released Debug configuration with slow code execution. I would rather create new solution from scratch to be sure that all setting are correct.

Sounds good, although if you could fix bcl.vcxproj too, I would appreciate it. It's for the library.

Also, if you could figure out how to make dc.exe link to bc.exe, I would love that too.

A little bit confused of compiler definitions:

Is that all correct?

Yes, it is all correct, and I'll try to explain what they mean.

BC_ENABLED=1
DC_ENABLED=1

These make sure both calculators are enabled. If you set DC_ENABLED to 0, you can make sure that only bc is built, for example.

Having both enabled is the only supported build on Windows. In fact, what I have set all of these options to are the only supported build.

BC_ENABLE_EXTRA_MATH=1

Without this option, bc would not have the extra functions you want.

BC_ENABLE_HISTORY=1

This option makes bc have history for input. You can use the up arrow to see lines that you previously entered, among other things.

BC_ENABLE_NLS=0

This option enables locale support, if it's enabled. However, locale support is based on POSIX locales, which just won't work on Windows, which is why this is disabled.

BC_DEBUG_CODE=0

This is for development only. In release builds, or even debug builds that users get, this should always be 0 because it adds a lot of debug code that I don't normally need.

BC_ENABLE_LIBRARY=0

There is a way of building a library of bc's math code. This option is what controls that. In bc.vcxproj, this should be 0, but in bcl.vcxproj, this should be 1.

EXECSUFFIX=.exe

This ensures that the .exe that Windows expects executables to have will be there.

BUILD_TYPE=N

With all of the different build options available for bc on POSIX-compatible systems, there needs to be some way for users to know which online manual to consult if they need help, so if users run bc --help, they get:

bc <TAG>
Copyright (c) 2018-2021 Gavin D. Howard and contributors
Report bugs at: https://git.yzena.com/gavin/bc

This is free software with ABSOLUTELY NO WARRANTY.

usage: bc [options] [file...]

bc is a command-line, arbitrary-precision calculator with a Turing-complete
language. For details, use `man bc` or see the online documentation at
https://git.yzena.com/gavin/bc/src/tag/<TAG>/manuals/bc/<BUILD_TYPE>.1.md.

where <BUILD_TYPE> is replaced by the value of BUILD_TYPE. In the case of Windows, the build type is N, which means that locales are disabled, but everything else is enabled.

(Also, <TAG> is replaced by the version of bc, so you would see 5.0.1.)

That gives them an actual URL to go to for the full manual. This is important for Windows users since they cannot use manpages, which is the form the manuals take on POSIX-compatible systems.

BC_DEFAULT_BANNER=1
BC_DEFAULT_SIGINT_RESET=0
DC_DEFAULT_SIGINT_RESET=0
BC_DEFAULT_TTY_MODE=1
DC_DEFAULT_TTY_MODE=1
BC_DEFAULT_PROMPT=1
DC_DEFAULT_PROMPT=1

These set some defaults for a few settings that bc and dc use. Please keep them the same.

You can see more about these options in the Standard Macros section of the development manual.

Also, strgen custom build for internal scripts and help text is unexpected to see :blush:

The reason is because I want the text for internal scripts and help text to be internal to the binary. I don't want the binary to depend on outside files, except what libraries I have to rely on.

So strgen takes those files and turns them into character arrays in C files, which are then used by the build. You can read more about that in the strgen.c section of the development manual.

I'll try to create pull request to fix things a little bit later, if you don't mind

Feel free, but please don't be too upset if I am a little picky. The reason is because I want to understand what the files are doing so that I can fix it later, if need be.

depler commented 2 years ago

Fixes: https://github.com/gavinhoward/bc/pull/38