{"id":22443046,"url":"https://github.com/veltzer/fcmp","last_synced_at":"2025-10-12T10:12:27.342Z","repository":{"id":2389627,"uuid":"3355601","full_name":"veltzer/fcmp","owner":"veltzer","description":"Fcmp is a library to compare two floating point numbers","archived":false,"fork":false,"pushed_at":"2025-08-30T23:25:57.000Z","size":92,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-12T10:12:26.947Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://github.com/veltzer/fcmp/","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/veltzer.png","metadata":{"files":{"readme":"README","changelog":"ChangeLog","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2012-02-04T21:41:05.000Z","updated_at":"2025-08-30T23:26:00.000Z","dependencies_parsed_at":"2023-01-11T16:09:47.850Z","dependency_job_id":"ea4b0ecd-5164-4323-af30-c2d61b2e90c2","html_url":"https://github.com/veltzer/fcmp","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/veltzer/fcmp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/veltzer%2Ffcmp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/veltzer%2Ffcmp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/veltzer%2Ffcmp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/veltzer%2Ffcmp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/veltzer","download_url":"https://codeload.github.com/veltzer/fcmp/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/veltzer%2Ffcmp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279011050,"owners_count":26084863,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-12T02:00:06.719Z","response_time":53,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-06T02:22:09.475Z","updated_at":"2025-10-12T10:12:27.294Z","avatar_url":"https://github.com/veltzer.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"************************************************************************\nfcmp\nCopyright (c) 1998-2000 Theodore C. Belding\nUniversity of Michigan Center for the Study of Complex Systems\n\u003cmailto:Ted.Belding@umich.edu\u003e\n\u003chttp://www-personal.umich.edu/~streak/\u003e                \n\nThis file is part of the fcmp distribution. fcmp is free software; you\ncan redistribute and modify it under the terms of the GNU Library\nGeneral Public License (LGPL), version 2 or later.  This software\ncomes with absolutely no warranty. See the file COPYING for details\nand terms of copying.\n\nFile: README \n\nDescription: README documentation file\n************************************************************************\n\nFCMP: SAFER COMPARISON OF FLOATING-POINT NUMBERS\n\nIt is generally not wise to compare two floating-point values for\nexact equality, for example using the C == operator.  The fcmp package\nimplements Knuth's [1] suggestions for safer floating-point comparison\noperators as a C function.\n\nFCMP HOMEPAGE AND CURRENT RELEASES\n\nThe fcmp homepage is at \u003chttp://fcmp.sourceforge.net/\u003e. There you can\nalways find the current release of fcmp, as well as the fcmp CVS\nsource code repository, which is available for anonymous read-only\naccess.\n\nTo receive announcements of new fcmp releases, you can subscribe to\nthe fcmp-announce email list by visiting the web page\n\u003chttp://lists.sourceforge.net/mailman/listinfo/fcmp-announce\u003e or by\nsending an email to \u003cfcmp-announce-request@lists.sourceforge.net\u003e with\nthe body \"subscribe\". fcmp-announce is a very low volume list for fcmp\nannouncements only.\n\nREPORTING BUGS \n\nTo report a bug in fcmp, visit the fcmp bug tracking system on the web\nat \u003chttp://sourceforge.net/bugs/?group_id=1799\u003e or send an email to\n\u003cfcmp-bugs@lists.sourceforge.net\u003e (the web page is the preferred\nmethod). Please give full details about the bug, including what fcmp\nversion, platform, OS, and compiler you used.\n\nINSTALLATION\n\nThe easiest way to use fcmp is simply to include the source code in\nyour program. If you are using Windows 95/98, MacOS, or some other\nnon-Unix platform, this is currently the only available way to use\nfcmp.\n\nIt is also possible to compile and install fcmp as a static or a\nshared library on Unix-compatible platforms.  See the file INSTALL for\nfull instructions on how to do this.\n\nYou can control which versions of the library are compiled and\ninstalled using the configure script.  To compile and install only the\nstatic library version of fcmp, run configure with the flag\n\"--disable-shared\". To compile and install only the shared library\nversion, run configure with the flag \"--disable-static\". By default,\nboth static and shared libraries are produced.\n\nNote: If you are the system administrator and are installing the\nshared library version of fcmp as a system library on a\nUnix-compatible platform, then you must make sure that the dynamic\nloader can find the shared library at run time.  On Linux, you should\nadd the path of the library's directory to the file /etc/ld.so.conf,\nif it is not already present. Then run ldconfig.\n\nSimilarly, if you installed the shared library version of fcmp in your\nhome directory, you will have to tell the dynamic loader where to find\nthe library, since it is not in one of the standard locations.  On\nLinux, add the path of the directory in which you installed it to your\nLD_LIBRARY_PATH environment variable.  For example, if you use bash as\nyour shell and you installed fcmp in ~/local/fcmp in your home\ndirectory, then you should add the following line to your\n.bash_profile file:\n\nexport LD_LIBRARY_PATH=$HOME/local/fcmp/lib:$LD_LIBRARYPATH\n\nUSING FCMP\n\nIf you have installed the fcmp library, you can use it in your\nprograms by just including the header file \"fcmp.h\" and linking your\nprogram with the flag \"-lfcmp\". You will also have to tell the\ncompiler where to find the fcmp header file and library, if they are\nnot already on the compiler's search path. For instance, if you're\nusing gcc on a Unix-like platform and you installed fcmp in\n/usr/local/fcmp:\n\ngcc -I/usr/local/fcmp/include -L/usr/local/fcmp/lib foo.c -lfcmp\n\nOf course, if you prefer, you can just include the source code in your\nprogram, rather than using the fcmp libraries.\n\nThe fcmp function prototype is:\n\nint fcmp(double x1, double x2, double epsilon);\n\nwhere x1 and x2 are two floating-point numbers to be compared, and\nepsilon determines the tolerance of the comparison (see the section\nBACKGROUND for details). \n\nfcmp returns -1 if x1 is less than x2, 0 if x1 is equal to x2, and 1\nif x1 is greater than x2 (relative to the tolerance).\n\nFor example, the following program should print \"the result is: 1\"\n\n#include \"fcmp.h\"\n#include \u003cfloat.h\u003e\n#include \u003cstdio.h\u003e\n\nint main() {\n  int result;\n  result = fcmp(3.0, 2.0, DBL_EPSILON);\n  printf(\"the result is: %d\\n\", result);\n  return 0;\n}\n\nBACKGROUND \n\nFloating point numbers are inherently inexact, and comparisons between\nthem are also inexact.  Equality or `==' comparisons are particularly\nunreliable.  In the following code snippet, x is unlikely to be\nexactly equal to y, even if both variable nominally have the same\nvalue. This is due to sources of error such as truncation error and\nrounding error.\n\nfloat x;\nfloat y;\n\n/* calculations */\n\nif (x == y) { /* unlikely to work! */\n  /* code to be executed if x == y */\n}\n\nFor example, the following program (from Priest [3]) may produce the\noutput \"Equal\" or \"Not Equal\", depending on the platform, compiler,\nand compile-time options that are used:\n\n#include \u003cstdio.h\u003e\n\nint main() {\n    double q;\n\n    q = 3.0/7.0;\n    if (q == 3.0/7.0) printf(\"Equal\\n\");\n    else printf(\"Not Equal\\n\");\n    return 0;\n}\n\nThe same problem holds for `\u003c', `\u003e', `\u003c=', `\u003e=', and `!=' comparisons.\nSince equality cannot be exactly determined with floating point\nnumbers, inequality cannot either.  \n\nWhat is needed is a comparison operator that takes into account a\ncertain amount of uncertainty:\n\nif (fabs(x - y) \u003c= epsilon) {\n  /* code to be executed if x == y */\n}\n\nif (x - y \u003e epsilon) {\n  /* code to be executed if x \u003e y */\n}\n\nif (x - y \u003c -epsilon) {\n  /* code to be executed if x \u003c y */\n}\n\nIn the above code, a neighborhood is defined that extends a distance\nepsilon to either side of y on the real number line.  If x falls\nwithin epsilon of y, x is declared to be equal to y (the first case,\nabove).  If x is greater than y by an amount that is greater than\nepsilon, x is declared to be greater than y (the second case, above).\nIf x is less than y by an amount that is greater than epsilon, x is\ndeclared to be less than y (the third case, above).\n\nThe problem then becomes to determine an appropriate value of epsilon.\nA fixed value of epsilon would not work for all x and y; epsilon\nshould be scaled larger or smaller depending on the magnitudes of the\nnumbers to be compared.\n\nA floating point number is represented by two numbers, the significand\n(also called the fraction or mantissa) and the exponent, and a sign,\nwhere\n\n0 \u003c= significand \u003c 1 \n\nand \n\nnumber = sign * significand * pow(2, exponent).\n\nKnuth's suggestion is to scale epsilon by the exponent of the larger of the\ntwo floating point numbers to be compared:\n\ndelta = epsilon * maxExponent,\n\nwhere maxExponent is the exponent of max(x, y).  Delta can then be\nsubstituted for epsilon in the code snippets above.\n\nThe routine fcmp() in this package implements Knuth's comparison\noperators.  Given a value for epsilon, and two float or double numbers\nx and y, it returns 1 if x is determined to be greater than y, 0 if x\nequals y, and -1 if x is less than y.  (The routine automatically\nconverts floats to doubles, since there is no single-precision\nequivalent for the standard C routines frexp() and ldexp(). However,\nit works for both floats and doubles, without modification.)\n\nDETERMINING EPSILON\n\nNow that we have found a way to scale epsilon to work with a wide\nrange of x and y, we still need to choose an appropriate epsilon,\nbefore scaling.  \n\nIf the number of binary digits of error, e, is known, then epsilon\ncan be calculated as follows:\n\nepsilon = (pow(2, e) - 1) * FLT_EPSILON         (for floats)\nepsilon = (pow(2, e) - 1) * DBL_EPSILON         (for doubles)\n\nFLT_EPSILON and DBL_EPSILON are equivalent to 1 ulp for single- and\ndouble-precision numbers, respectively; they are defined in the\nstandard C header file \u003cfloat.h\u003e. (An ulp is one unit in the last\nplace of the significand, or fraction part, of a floating point\nnumber; see Knuth[1] for more details.)\n\nTIMING RESULTS\n\nTo measure the performance penalty caused by using fcmp() instead\nof normal floating-point comparisons such as \u003c, I ran 4 different\nbenchmarks. In each benchmark except the first, which simply \nmeasured the overhead of the non-comparison portions of the program, \n60000000 comparisons were executed. The results are:\n\ncomparison type         total user seconds      seconds/comparison\n\nno comparisons          31.55                   N/A\n\u003c (normal)              35.32                   6.28e-8\nfcmp                    66.36                   5.80e-7\nfcmp2                   66.62                   5.85e-7\n\nThe platform was a 266 MHz Pentium II, running Redhat 5.1 and egcs 1.1\n(installed for i386-redhat-linux). All programs were compiled with\n-O3. \"fcmp2\" is a variant of fcmp, where the formula\n\nepsilon * max(fabs(x1), fabs(x2)) \n\nis used instead of \n\nepsilon * b^e(max(fabs(x1), fabs(x2)))\n\nIn summary, fcmp() is 9.23 times slower than normal floating point\ncomparisons (\u003c).\n\nThis may seem like a huge performance hit, but it will not actually\nhave a major impact on program speed unless fcmp() is used in an\ninner loop or another bottleneck within the program. As always, you \nshould profile your program to see where the bottlenecks are before\nattempting to optimize the program by hand for speed.\n\nAt some point in the future, I hope to make it possible to use fcmp as\na C macro, to avoid the overhead of calling it as a function.\n\nBIBLIOGRAPHY\n\n[2] Goldberg, David. (1991). What every computer scientist should know\nabout floating-point arithmetic. ACM Computing Surveys 23(1): 5-48.\nOnline at \u003chttp://www.validgh.com/goldberg/paper.ps\u003e. The online\nversion includes an addendum by Doug Priest [3].\n\nGoldberg, David. (1996). Computer arithmetic. Appendix A in Hennessy,\nJohn L., and David A. Patterson, Computer Architecture: A Quantitative\nApproach. Second edition. pp. A1-A77. San Francisco: Morgan\nKaufmann. ISBN 1-55860-329-9.\n\n[1] Knuth, Donald E. (1998). The Art of Computer Programming.  Volume\n2: Seminumerical Algorithms. Third edition. Section 4.2.2,\np. 233. Reading, MA: Addison-Wesley.  ISBN 0-201-89684-2.\n\nPatterson, David A., and John L. Hennessy. (1998). Arithmetic for\ncomputers. Chapter 4 in Computer Organization and Design: The\nHardware/Software Interface. Second edition. pp. 208-335. San\nFrancisco: Morgan Kaufmann. ISBN 1-55860-428-6. A more basic\nintroduction than Goldberg or Knuth.\n\n[3] Priest, Doug. (1997). Differences among IEEE 754 implementations.\nAddendum to Goldberg's [2] paper. Online at\n\u003chttp://www.validgh.com/goldberg/addendum.html\u003e and\n\u003chttp://www.validgh.com/goldberg/paper.ps\u003e; the latter version\nincludes Goldberg's [2] paper.\n\nSummit, Steve. (1996). C Programming FAQs: Frequently Asked\nQuestions. Question 14.5, pp. 250-251. Reading, MA:\nAddison-Wesley. ISBN 0-201-84519-9. Another algorithm for comparing\nfloating-point numbers.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fveltzer%2Ffcmp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fveltzer%2Ffcmp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fveltzer%2Ffcmp/lists"}