<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>http://wiki.bgcottrell.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Root</id>
	<title>Personal Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.bgcottrell.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Root"/>
	<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php/Special:Contributions/Root"/>
	<updated>2026-05-05T14:22:21Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.45.1</generator>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=Common_Algorithms&amp;diff=82</id>
		<title>Common Algorithms</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=Common_Algorithms&amp;diff=82"/>
		<updated>2026-02-15T22:04:40Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Software Development]]&lt;br /&gt;
The code published on this page is provided with the conditions of the MIT license.&lt;br /&gt;
&lt;br /&gt;
== Arbitrary Number Base Conversion ==&lt;br /&gt;
TODO: This version converts to and from base-[2-10], but doesn&#039;t support input validation. Hexadecimal and base64 should be supported as well.&lt;br /&gt;
&lt;br /&gt;
=== JavaScript ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;function baseNToBaseTen(inputValue, inputBase) {&lt;br /&gt;
    var inputValueStr = inputValue.toString();&lt;br /&gt;
    var sum = 0;&lt;br /&gt;
    for (var i=inputValueStr.length-1; i&amp;gt;=0; i--) {&lt;br /&gt;
        sum += Number(inputValueStr[i])*Math.pow(inputBase,inputValueStr.length-1-i);&lt;br /&gt;
    }&lt;br /&gt;
    return sum;&lt;br /&gt;
}&lt;br /&gt;
function convertInputValue(inputValue,inputBase,outputBase)&lt;br /&gt;
{&lt;br /&gt;
    var resultText = &amp;quot;&amp;quot;;&lt;br /&gt;
    var quot=inputValue, rem=0, rounded=Math.floor(inputValue);&lt;br /&gt;
    if (inputBase === 10) {&lt;br /&gt;
        while (rounded &amp;gt; 0) {&lt;br /&gt;
            rem = rounded % outputBase;&lt;br /&gt;
            resultText = rem.toString() + resultText;&lt;br /&gt;
            quot = quot / outputBase;&lt;br /&gt;
            rounded = Math.floor(quot);&lt;br /&gt;
        }&lt;br /&gt;
    } else {&lt;br /&gt;
        var bTenValue = baseNToBaseTen(inputValue, inputBase)&lt;br /&gt;
        if (outputBase === 10) {&lt;br /&gt;
            resultText = bTenValue.toString();&lt;br /&gt;
        } else {&lt;br /&gt;
            convertInputValue(bTenValue, 10, outputBase);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return resultText;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Integer to Words ==&lt;br /&gt;
This converts an integer into English words. Solving this problem was an interesting exercise, as I ended up parsing in 3 stages which were: splitting the digit groups, inserting symbols for base 10 exponents and ampersands after groups of hundreds, and then converting the symbols into words.&lt;br /&gt;
&lt;br /&gt;
I initially started my implementation in Java, then after finishing, moved onto C++. The Rust version was the most difficult, as, of time of writing it, I was still fairly new to the language.&lt;br /&gt;
&lt;br /&gt;
=== Java ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
package com.bgcottrell;&lt;br /&gt;
&lt;br /&gt;
import java.util.*;&lt;br /&gt;
&lt;br /&gt;
public class Main {&lt;br /&gt;
    public static String[] E0Literals = &amp;quot;zero,one,two,three,four,five,six,seven,eight,nine&amp;quot;.split(&amp;quot;,&amp;quot;);&lt;br /&gt;
    public static String[] TNLiterals = &amp;quot;eleven,twelve,thirteen,fourteen,fifteen,sixteen,seventeen,eighteen,nineteen&amp;quot;.split(&amp;quot;,&amp;quot;);&lt;br /&gt;
    public static String[] E1Literals = &amp;quot;ten,twenty,thirty,forty,fifty,sixty,seventy,eighty,ninety&amp;quot;.split(&amp;quot;,&amp;quot;);&lt;br /&gt;
    public static String parseIntString(String strValue)&lt;br /&gt;
    {&lt;br /&gt;
        StringBuilder result = new StringBuilder();&lt;br /&gt;
        Long parsedValue = 0L;&lt;br /&gt;
        //int r = 0;&lt;br /&gt;
        try {&lt;br /&gt;
            parsedValue = Long.parseUnsignedLong(strValue);&lt;br /&gt;
            //r = strValue.length();&lt;br /&gt;
        } catch (NumberFormatException e) {&lt;br /&gt;
            throw new RuntimeException(e);&lt;br /&gt;
        }&lt;br /&gt;
        // Split with commas&lt;br /&gt;
        int numCommas = (int)Math.ceil((double) strValue.length() /6);&lt;br /&gt;
        StringBuilder tokens = new StringBuilder(strValue.length() + numCommas);&lt;br /&gt;
        if (strValue.length() &amp;lt; 4) {&lt;br /&gt;
            for (int i = strValue.length() - 1; i &amp;gt;= 0; i--) {&lt;br /&gt;
                tokens.insert(0, strValue.charAt(i));&lt;br /&gt;
            }&lt;br /&gt;
        } else {&lt;br /&gt;
            for (int i = strValue.length() - 1; i &amp;gt;= 0; i--) {&lt;br /&gt;
                tokens.insert(0, strValue.charAt(i));&lt;br /&gt;
                if ((strValue.length() - i) % 3 == 0 &amp;amp;&amp;amp; (i &amp;gt; 0)) {&lt;br /&gt;
                    tokens.insert(0, &#039;,&#039;);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        System.out.printf(&amp;quot;(%s) &amp;quot;,tokens);&lt;br /&gt;
&lt;br /&gt;
        // Parse, insert exponents, hundred&#039;s joiners&lt;br /&gt;
        String groups[] = tokens.toString().split(&amp;quot;,&amp;quot;);&lt;br /&gt;
        ArrayList&amp;lt;String&amp;gt; parserTokens = new ArrayList&amp;lt;&amp;gt;();&lt;br /&gt;
        for (int gi=0; gi &amp;lt; groups.length; gi++) {&lt;br /&gt;
            switch (groups[gi].length()) {&lt;br /&gt;
                case 3: {&lt;br /&gt;
                    Integer p[] = {&lt;br /&gt;
                            Integer.parseUnsignedInt(String.valueOf(groups[gi].charAt(0))),&lt;br /&gt;
                            Integer.parseUnsignedInt(groups[gi].substring(1)),&lt;br /&gt;
                    };&lt;br /&gt;
                    if (p[0] != 0) {&lt;br /&gt;
                        parserTokens.add(E0Literals[p[0]]);&lt;br /&gt;
                        parserTokens.add(&amp;quot;H&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    if (p[1] != 0 &amp;amp;&amp;amp; p[1] &amp;lt; 10) {&lt;br /&gt;
                        parserTokens.add(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                        parserTokens.add(E0Literals[p[1]]);&lt;br /&gt;
                    } else if (p[1] != 0 &amp;amp;&amp;amp; p[1] &amp;lt; 20) {&lt;br /&gt;
                        parserTokens.add(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                        parserTokens.add(TNLiterals[p[1] - 11]);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        if (groups[gi].charAt(1) != &#039;0&#039;) {&lt;br /&gt;
                            parserTokens.add(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                            parserTokens.add(&lt;br /&gt;
                                    E1Literals[Integer.parseUnsignedInt(String.valueOf(groups[gi].charAt(1))) - 1]&lt;br /&gt;
                            );&lt;br /&gt;
                        }&lt;br /&gt;
                        if (groups[gi].charAt(2) != &#039;0&#039;) {&lt;br /&gt;
                            parserTokens.add(&lt;br /&gt;
                                E0Literals[Integer.parseUnsignedInt(String.valueOf(groups[gi].charAt(2)))]&lt;br /&gt;
                            );&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
                case 2:&lt;br /&gt;
                {&lt;br /&gt;
                    Integer p = Integer.parseUnsignedInt(groups[gi]);&lt;br /&gt;
                    if (p &amp;lt; 10) {&lt;br /&gt;
                        parserTokens.add(E0Literals[p]);&lt;br /&gt;
                    } else if (p &amp;lt; 20) {&lt;br /&gt;
                        parserTokens.add(TNLiterals[p - 11]);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        parserTokens.add(&lt;br /&gt;
                                E1Literals[Integer.parseUnsignedInt(String.valueOf(groups[gi].charAt(0))) - 1]&lt;br /&gt;
                        );&lt;br /&gt;
                        if (groups[gi].charAt(1) != &#039;0&#039;) {&lt;br /&gt;
                            parserTokens.add(&lt;br /&gt;
                                    E0Literals[Integer.parseUnsignedInt(String.valueOf(groups[gi].charAt(1)))]&lt;br /&gt;
                            );&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
                case 1: {&lt;br /&gt;
                    Integer p = Integer.parseUnsignedInt(groups[gi]);&lt;br /&gt;
                    parserTokens.add(E0Literals[p]);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            if (gi == groups.length - 2 &amp;amp;&amp;amp; groups[gi] != &amp;quot;000&amp;quot;) {&lt;br /&gt;
                parserTokens.add(&amp;quot;T&amp;quot;);&lt;br /&gt;
            } else if (gi == groups.length - 3) {&lt;br /&gt;
                parserTokens.add(&amp;quot;M&amp;quot;);&lt;br /&gt;
            } else if (gi == groups.length - 4) {&lt;br /&gt;
                parserTokens.add(&amp;quot;B&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        //System.out.printf(&amp;quot;Parsed: %s&amp;quot;, parserTokens);&lt;br /&gt;
        for (int i =0; i &amp;lt; parserTokens.size() - 1;i++) {&lt;br /&gt;
            switch (parserTokens.get(i)) {&lt;br /&gt;
                case &amp;quot;H&amp;quot;:&lt;br /&gt;
                    result.append(&amp;quot;hundred&amp;quot;);&lt;br /&gt;
                    break;&lt;br /&gt;
                case &amp;quot;T&amp;quot;:&lt;br /&gt;
                    result.append(&amp;quot;thousand&amp;quot;);&lt;br /&gt;
                    break;&lt;br /&gt;
                case &amp;quot;M&amp;quot;:&lt;br /&gt;
                    result.append(&amp;quot;million&amp;quot;);&lt;br /&gt;
                    break;&lt;br /&gt;
                case &amp;quot;B&amp;quot;:&lt;br /&gt;
                    result.append(&amp;quot;billion&amp;quot;);&lt;br /&gt;
                    break;&lt;br /&gt;
                case &amp;quot;&amp;amp;&amp;quot;:&lt;br /&gt;
                    result.append(&amp;quot;and&amp;quot;);&lt;br /&gt;
                    break;&lt;br /&gt;
                default:&lt;br /&gt;
                    result.append(parserTokens.get(i));&lt;br /&gt;
            }&lt;br /&gt;
            result.append(&amp;quot; &amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        switch (parserTokens.getLast()) {&lt;br /&gt;
            case &amp;quot;H&amp;quot;:&lt;br /&gt;
                result.append(&amp;quot;hundred&amp;quot;);&lt;br /&gt;
                break;&lt;br /&gt;
            case &amp;quot;T&amp;quot;:&lt;br /&gt;
                result.append(&amp;quot;thousand&amp;quot;);&lt;br /&gt;
                break;&lt;br /&gt;
            case &amp;quot;M&amp;quot;:&lt;br /&gt;
                result.append(&amp;quot;million&amp;quot;);&lt;br /&gt;
                break;&lt;br /&gt;
            case &amp;quot;B&amp;quot;:&lt;br /&gt;
                result.append(&amp;quot;billion&amp;quot;);&lt;br /&gt;
            case &amp;quot;&amp;amp;&amp;quot;:&lt;br /&gt;
                result.append(&amp;quot;and&amp;quot;);&lt;br /&gt;
            default:&lt;br /&gt;
                result.append(parserTokens.getLast());&lt;br /&gt;
        }&lt;br /&gt;
        return result.toString();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== C++17 ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;cmath&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;iomanip&amp;gt;&lt;br /&gt;
#include &amp;lt;vector&amp;gt;&lt;br /&gt;
#include &amp;lt;ranges&amp;gt;&lt;br /&gt;
#include &amp;lt;string_view&amp;gt;&lt;br /&gt;
#include &amp;lt;algorithm&amp;gt;&lt;br /&gt;
#include &amp;lt;format&amp;gt;&lt;br /&gt;
static string IntToWords(const string&amp;amp; input)&lt;br /&gt;
{&lt;br /&gt;
    static array E0Literals = {&amp;quot;zero&amp;quot;, &amp;quot;one&amp;quot;, &amp;quot;two&amp;quot;, &amp;quot;three&amp;quot;, &amp;quot;four&amp;quot;, &amp;quot;five&amp;quot;, &amp;quot;six&amp;quot;, &amp;quot;seven&amp;quot;, &amp;quot;eight&amp;quot;, &amp;quot;nine&amp;quot;};&lt;br /&gt;
    static array TNLiterals = {&amp;quot;eleven&amp;quot;, &amp;quot;twelve&amp;quot;, &amp;quot;thirteen&amp;quot;, &amp;quot;fourteen&amp;quot;, &amp;quot;fifteen&amp;quot;, &amp;quot;sixteen&amp;quot;, &amp;quot;seventeen&amp;quot;, &amp;quot;eighteen&amp;quot;, &amp;quot;nineteen&amp;quot;};&lt;br /&gt;
    static array E1Literals = {&amp;quot;ten&amp;quot;, &amp;quot;twenty&amp;quot;, &amp;quot;thirty&amp;quot;, &amp;quot;forty&amp;quot;, &amp;quot;fifty&amp;quot;, &amp;quot;sixty&amp;quot;, &amp;quot;seventy&amp;quot;, &amp;quot;eighty&amp;quot;, &amp;quot;ninety&amp;quot;};&lt;br /&gt;
    string result;&lt;br /&gt;
    try {&lt;br /&gt;
        ulong parsedValue = stoul(input);&lt;br /&gt;
    } catch (const exception&amp;amp; ex) {&lt;br /&gt;
        return &amp;quot;invalid&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    // Split with commas, make it easier to parse&lt;br /&gt;
    const auto numCommas = int(ceil(input.length()/6));&lt;br /&gt;
    string tokens;&lt;br /&gt;
    tokens.reserve(input.length()+numCommas);&lt;br /&gt;
    if (input.length() &amp;lt; 4) {&lt;br /&gt;
        for (int i=input.length()-1;i&amp;gt;=0;i--) {&lt;br /&gt;
            tokens.insert(tokens.begin(), input.at(i));&lt;br /&gt;
        }&lt;br /&gt;
    } else {&lt;br /&gt;
        for (int i=input.length()-1;i&amp;gt;=0;i--) {&lt;br /&gt;
            tokens.insert(tokens.begin(),input.at(i));&lt;br /&gt;
            if ((input.length() -i) % 3 == 0) {&lt;br /&gt;
                tokens.insert(tokens.begin(),&#039;,&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    // Parse, insert exponents, joiners&lt;br /&gt;
    vector&amp;lt;string&amp;gt; groups = split(tokens, &amp;quot;,&amp;quot;);&lt;br /&gt;
    vector&amp;lt;string&amp;gt; parserTokens;&lt;br /&gt;
    parserTokens.reserve(input.length()*2);&lt;br /&gt;
    for (size_t gi=0; gi != groups.size(); gi++) {&lt;br /&gt;
        switch (groups[gi].length()) {&lt;br /&gt;
        case 3:&lt;br /&gt;
        {&lt;br /&gt;
            vector&amp;lt;int&amp;gt; p = {&lt;br /&gt;
                stoi(groups[gi].substr(0,1)),&lt;br /&gt;
                stoi(groups[gi].substr(1))&lt;br /&gt;
            };&lt;br /&gt;
            if (p[0] != 0) {&lt;br /&gt;
                parserTokens.push_back(E0Literals[p[0]]);&lt;br /&gt;
                parserTokens.push_back(&amp;quot;H&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            if (p[1] != 0 &amp;amp;&amp;amp; p[1] &amp;lt; 10) {&lt;br /&gt;
                parserTokens.push_back(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                parserTokens.push_back(E0Literals[p[1]]);&lt;br /&gt;
            } else if (p[1] != 0 &amp;amp;&amp;amp; p[1] &amp;lt; 20) {&lt;br /&gt;
                parserTokens.push_back(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                parserTokens.push_back(TNLiterals[p[1]-11]);&lt;br /&gt;
            } else {&lt;br /&gt;
                if (groups[gi].at(1) != &#039;0&#039;) {&lt;br /&gt;
                    parserTokens.push_back(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                    parserTokens.push_back(&lt;br /&gt;
                        E1Literals[stoi(groups[gi].substr(1,1))-1]&lt;br /&gt;
                    );&lt;br /&gt;
                }&lt;br /&gt;
                if (groups[gi].at(2) != &#039;0&#039;) {&lt;br /&gt;
                    parserTokens.push_back(&lt;br /&gt;
                        E0Literals[stoi(groups[gi].substr(2,1))]&lt;br /&gt;
                    );&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        case 2:&lt;br /&gt;
        {&lt;br /&gt;
            int p = stoi(groups[gi]);&lt;br /&gt;
            if (p &amp;lt; 10) {&lt;br /&gt;
                parserTokens.push_back(E0Literals[p]);&lt;br /&gt;
            } else if (p &amp;lt; 20) {&lt;br /&gt;
                parserTokens.push_back(TNLiterals[p-11]);&lt;br /&gt;
            } else {&lt;br /&gt;
                parserTokens.push_back(&lt;br /&gt;
                    E1Literals[stoi(groups[gi].substr(0,1))-1]&lt;br /&gt;
                );&lt;br /&gt;
                if (groups[gi].at(1) != &#039;0&#039;) {&lt;br /&gt;
                    parserTokens.push_back(&lt;br /&gt;
                        E0Literals[stoi(groups[gi].substr(1,1))]&lt;br /&gt;
                    );&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        case 1:&lt;br /&gt;
        {&lt;br /&gt;
            int p = stoi(groups[gi]);&lt;br /&gt;
            parserTokens.push_back(E0Literals[p]);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        } /* switch */&lt;br /&gt;
        if (gi == groups.size() - 2 &amp;amp;&amp;amp; groups[gi] != &amp;quot;000&amp;quot;) {&lt;br /&gt;
            parserTokens.push_back(&amp;quot;T&amp;quot;);&lt;br /&gt;
        } else if (gi == groups.size() - 3) {&lt;br /&gt;
            parserTokens.push_back(&amp;quot;M&amp;quot;);&lt;br /&gt;
        } else if (gi == groups.size() - 4) {&lt;br /&gt;
            parserTokens.push_back(&amp;quot;B&amp;quot;);&lt;br /&gt;
        } else if (gi == groups.size() - 5) {&lt;br /&gt;
            parserTokens.push_back(&amp;quot;Tr&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        } /* for */&lt;br /&gt;
        for (int i=0; i &amp;lt; parserTokens.size() - 1; i++) {&lt;br /&gt;
            string s = parserTokens.at(i);&lt;br /&gt;
            if (s == &amp;quot;H&amp;quot;) {&lt;br /&gt;
                result.append(&amp;quot;hundred&amp;quot;);&lt;br /&gt;
            } else if (s == &amp;quot;T&amp;quot;) {&lt;br /&gt;
                result.append(&amp;quot;thousand&amp;quot;);&lt;br /&gt;
            } else if (s == &amp;quot;M&amp;quot;) {&lt;br /&gt;
                result.append(&amp;quot;million&amp;quot;);&lt;br /&gt;
            } else if (s == &amp;quot;B&amp;quot;) {&lt;br /&gt;
                result.append(&amp;quot;billion&amp;quot;);&lt;br /&gt;
            } else if (s == &amp;quot;Tr&amp;quot;) {&lt;br /&gt;
                result.append(&amp;quot;trillion&amp;quot;);&lt;br /&gt;
            } else if (s == &amp;quot;&amp;amp;&amp;quot;) {&lt;br /&gt;
                result.append(&amp;quot;and&amp;quot;);&lt;br /&gt;
            } else {&lt;br /&gt;
                result.append(s);&lt;br /&gt;
            }&lt;br /&gt;
            result.append(&amp;quot; &amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        auto s = parserTokens.back();&lt;br /&gt;
        if (s == &amp;quot;H&amp;quot;) {&lt;br /&gt;
            result.append(&amp;quot;hundred&amp;quot;);&lt;br /&gt;
        } else if (s == &amp;quot;T&amp;quot;) {&lt;br /&gt;
            result.append(&amp;quot;thousand&amp;quot;);&lt;br /&gt;
        } else if (s == &amp;quot;M&amp;quot;) {&lt;br /&gt;
            result.append(&amp;quot;million&amp;quot;);&lt;br /&gt;
        } else if (s == &amp;quot;B&amp;quot;) {&lt;br /&gt;
            result.append(&amp;quot;billion&amp;quot;);&lt;br /&gt;
        } else if (s == &amp;quot;Tr&amp;quot;) {&lt;br /&gt;
            result.append(&amp;quot;trillion&amp;quot;);&lt;br /&gt;
        } else if (s == &amp;quot;&amp;amp;&amp;quot;) {&lt;br /&gt;
            result.append(&amp;quot;and&amp;quot;);&lt;br /&gt;
        } else {&lt;br /&gt;
            result.append(s);&lt;br /&gt;
        }&lt;br /&gt;
    return result;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rust ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;rust&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
use std::iter::Iterator;&lt;br /&gt;
use std::ops::Deref;&lt;br /&gt;
use std::str::FromStr;&lt;br /&gt;
struct IntToWords;&lt;br /&gt;
impl IntToWords&lt;br /&gt;
{&lt;br /&gt;
    // Using Option, because I cannot figure out how to return generic errors&lt;br /&gt;
    pub fn parse_value(&amp;amp;self, input: &amp;amp;str) -&amp;gt; Option&amp;lt;String&amp;gt;&lt;br /&gt;
    {&lt;br /&gt;
        let E0Literals: Vec&amp;lt;&amp;amp;&#039;static str&amp;gt; = &amp;quot;zero,one,two,three,four,five,six,seven,eight,nine,ten&amp;quot;.split(&#039;,&#039;).collect();&lt;br /&gt;
        let TNLiterals: Vec&amp;lt;&amp;amp;&#039;static str&amp;gt; = &amp;quot;eleven,twelve,thirteen,fourteen,fifteen,sixteen,seventeen,eighteen,nineteen&amp;quot;.split(&#039;,&#039;).collect();&lt;br /&gt;
        let E1Literals: Vec&amp;lt;&amp;amp;&#039;static str&amp;gt; = &amp;quot;ten,twenty,thirty,forty,fifty,sixty,seventy,eighty,ninety&amp;quot;.split(&#039;,&#039;).collect();&lt;br /&gt;
        let mut result: String = String::from(&amp;quot;&amp;quot;);&lt;br /&gt;
        let parsed_value = u64::from_str(input);&lt;br /&gt;
        if parsed_value.is_err() {&lt;br /&gt;
            return Some(String::from(&amp;quot;invalid&amp;quot;));&lt;br /&gt;
        }&lt;br /&gt;
        let num_commas = (input.len() as f32/6.0).ceil();&lt;br /&gt;
        // Split into digit groups&lt;br /&gt;
        let mut tokens: String = &amp;quot;&amp;quot;.to_string();&lt;br /&gt;
        tokens.reserve(input.len()+num_commas as usize);&lt;br /&gt;
        if input.len() &amp;lt; 4 {&lt;br /&gt;
            let mut i = input.len()-1;&lt;br /&gt;
            loop {&lt;br /&gt;
                tokens.insert(0, input.chars().nth(i).unwrap());&lt;br /&gt;
                if i &amp;gt; 0 { i -= 1; } else { break; }&lt;br /&gt;
            }&lt;br /&gt;
        } else {&lt;br /&gt;
            let mut i = input.len()-1;&lt;br /&gt;
            loop {&lt;br /&gt;
                tokens.insert(0,input.chars().nth(i).unwrap());&lt;br /&gt;
                if i &amp;gt; 0 &amp;amp;&amp;amp; (input.len()-i) % 3 == 0 {&lt;br /&gt;
                    tokens.insert(0,&#039;,&#039;);&lt;br /&gt;
                }&lt;br /&gt;
                if i &amp;gt; 0 { i -= 1; } else { break; }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        // Parse the digit groups&lt;br /&gt;
        let groups : Vec&amp;lt;&amp;amp;str&amp;gt; = tokens.split(&#039;,&#039;).collect();&lt;br /&gt;
        let mut parser_tokens:Vec&amp;lt;&amp;amp;str&amp;gt; = Vec::new();&lt;br /&gt;
        for gi in 0..groups.len() {&lt;br /&gt;
            match groups[gi].len() {&lt;br /&gt;
                3 =&amp;gt; {&lt;br /&gt;
                    let p = [&lt;br /&gt;
                        usize::from_str(&amp;amp;groups[gi].chars().as_str()[0..1]).unwrap(),&lt;br /&gt;
                        usize::from_str(&amp;amp;groups[gi].chars().as_str()[1..]).unwrap()&lt;br /&gt;
                    ];&lt;br /&gt;
                    let p1 = (p[1] as f32/10_f32).floor() as u32;&lt;br /&gt;
                    let p2 = p[1] as u32 - (p1 as u32 * 10);&lt;br /&gt;
                    if p[0] != 0 {&lt;br /&gt;
                        parser_tokens.push(E0Literals[p[0]]);&lt;br /&gt;
                        parser_tokens.push(&amp;quot;H&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    if p[1] != 0 &amp;amp;&amp;amp; p[1] &amp;lt;= 10 {&lt;br /&gt;
                        parser_tokens.push(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                        parser_tokens.push(E0Literals[p[1]]);&lt;br /&gt;
                    } else if p[1] != 0 &amp;amp;&amp;amp; p[1] &amp;lt; 20 {&lt;br /&gt;
                        parser_tokens.push(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                        parser_tokens.push(TNLiterals[p[1] - 11]);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        if groups[gi].chars().nth(1).unwrap() != &#039;0&#039; {&lt;br /&gt;
                            parser_tokens.push(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                            parser_tokens.push(&lt;br /&gt;
                                E1Literals[p1 as usize - 1]&lt;br /&gt;
                            );&lt;br /&gt;
                        }&lt;br /&gt;
                        if groups[gi].chars().nth(2).unwrap() != &#039;0&#039; {&lt;br /&gt;
                            parser_tokens.push(&lt;br /&gt;
                                E0Literals[p2 as usize]&lt;br /&gt;
                            );&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                2 =&amp;gt; {&lt;br /&gt;
                    let p = usize::from_str(&amp;amp;groups[gi]).unwrap();&lt;br /&gt;
                    let p1 = (p as f32/10_f32).floor() as u32;&lt;br /&gt;
                    let p2 = p as u32 - (p1 * 10);&lt;br /&gt;
                    if p &amp;lt;= 10 {&lt;br /&gt;
                        parser_tokens.push(E0Literals[p]);&lt;br /&gt;
                    } else if p &amp;lt; 20 {&lt;br /&gt;
                        parser_tokens.push(TNLiterals[p - 11]);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        parser_tokens.push(&lt;br /&gt;
                            E1Literals[p1 as usize-1]&lt;br /&gt;
                        );&lt;br /&gt;
                        if groups[gi].chars().nth(1).unwrap() != &#039;0&#039; {&lt;br /&gt;
                            parser_tokens.push(&lt;br /&gt;
                                E0Literals[p2 as usize]&lt;br /&gt;
                            );&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                1 =&amp;gt; {&lt;br /&gt;
                    let p = usize::from_str(groups[gi]).unwrap();&lt;br /&gt;
                    parser_tokens.push(E0Literals[p]);&lt;br /&gt;
                }&lt;br /&gt;
                _ =&amp;gt; {}&lt;br /&gt;
            } /* match */&lt;br /&gt;
            if groups.len() &amp;gt;= 2 &amp;amp;&amp;amp; gi == groups.len() - 2 &amp;amp;&amp;amp; groups[gi] != &amp;quot;000&amp;quot; {&lt;br /&gt;
                parser_tokens.push(&amp;quot;T&amp;quot;);&lt;br /&gt;
            } else if groups.len() &amp;gt;= 3 &amp;amp;&amp;amp; gi == groups.len() - 3 {&lt;br /&gt;
                parser_tokens.push(&amp;quot;M&amp;quot;);&lt;br /&gt;
            } else if groups.len() &amp;gt;= 4 &amp;amp;&amp;amp; gi == groups.len() - 4 {&lt;br /&gt;
                parser_tokens.push(&amp;quot;B&amp;quot;);&lt;br /&gt;
            } else if groups.len() &amp;gt;= 5 &amp;amp;&amp;amp; gi == groups.len() - 5 {&lt;br /&gt;
                parser_tokens.push(&amp;quot;Tr&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        // Convert tokens to words&lt;br /&gt;
        for i in 0..parser_tokens.len() {&lt;br /&gt;
            let s = parser_tokens[i];&lt;br /&gt;
            result.push_str(match s {&lt;br /&gt;
                &amp;quot;H&amp;quot; =&amp;gt; &amp;quot;hundred&amp;quot;,&lt;br /&gt;
                &amp;quot;T&amp;quot; =&amp;gt; &amp;quot;thousand&amp;quot;,&lt;br /&gt;
                &amp;quot;M&amp;quot; =&amp;gt; &amp;quot;million&amp;quot;,&lt;br /&gt;
                &amp;quot;B&amp;quot; =&amp;gt; &amp;quot;billion&amp;quot;,&lt;br /&gt;
                &amp;quot;Tr&amp;quot; =&amp;gt; &amp;quot;trillion&amp;quot;,&lt;br /&gt;
                &amp;quot;&amp;amp;&amp;quot; =&amp;gt; &amp;quot;and&amp;quot;,&lt;br /&gt;
                _ =&amp;gt; s&lt;br /&gt;
            });&lt;br /&gt;
            result.push_str(&amp;quot; &amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        Some(result)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pub fn main() {&lt;br /&gt;
    let instance: IntToWords = IntToWords { };&lt;br /&gt;
    let test_numbers: Vec&amp;lt;&amp;amp;str&amp;gt; = Vec::from([&amp;quot;1001&amp;quot;,&amp;quot;10101010&amp;quot;,&amp;quot;1100001&amp;quot;,&amp;quot;1110001&amp;quot;,&amp;quot;26&amp;quot;,&amp;quot;13&amp;quot;,&amp;quot;210&amp;quot;]);&lt;br /&gt;
    for n in test_numbers {&lt;br /&gt;
        println!(&amp;quot;{:-15}: {}&amp;quot;, n, instance.parse_value(n).unwrap());&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Useful_Commands&amp;diff=81</id>
		<title>GNU Linux/Useful Commands</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Useful_Commands&amp;diff=81"/>
		<updated>2026-02-15T04:19:10Z</updated>

		<summary type="html">&lt;p&gt;Root: /* Virtual Machines */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Information Technology|GNU Linux]]&lt;br /&gt;
&lt;br /&gt;
== Desktop Environments ==&lt;br /&gt;
&lt;br /&gt;
=== Copy and Paste Between X11 and Wayland Clipboards ===&lt;br /&gt;
When running an application inside a root-full X11 session, within XWayland for example, it may not be able to access Wayland&#039;s clipboard directly (pasting doesn&#039;t work). The below commands require packages, which, on ArchLinux are named &amp;quot;xclip&amp;quot; and &amp;quot;wl-clipboard&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
To copy to the X11 clipboard from Wayland&#039;s clipboard use:&lt;br /&gt;
 bash -c &amp;quot;wl-paste | xclip -d &amp;quot;:2&amp;quot; -selection &amp;quot;clipboard&amp;quot;&amp;quot;&lt;br /&gt;
To paste from the X11 clipboard into Wayland&#039;s clipboard (where :2 is replaced with the X11 display name):&lt;br /&gt;
 bash -c &amp;quot;xclip -o -d &amp;quot;:2&amp;quot; -selection &amp;quot;clipboard&amp;quot; | wl-copy&amp;quot;&lt;br /&gt;
I placed the command lines inside a call to bash, as these were added to custom keyboard shortcuts, for my GNOME desktop settings.&lt;br /&gt;
&lt;br /&gt;
== File Conversion ==&lt;br /&gt;
&lt;br /&gt;
=== Batch Convert Man Pages into HTML files ===&lt;br /&gt;
Requires the &amp;lt;code&amp;gt;mandoc&amp;lt;/code&amp;gt; program to be installed.&lt;br /&gt;
 &amp;lt;code&amp;gt;mkdir html &amp;amp;&amp;amp; for x in .; do mandoc -Thtml -O man=./html/%N.%S.html,toc $x &amp;gt; html/$x.html; done&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Virtual Machines ==&lt;br /&gt;
I&#039;ve found this to be more useful than &amp;lt;code&amp;gt;guestmount&amp;lt;/code&amp;gt; (provided by the &amp;lt;code&amp;gt;libguestfs-tools&amp;lt;/code&amp;gt; package for Ubuntu), because it does not require superuser privileges to execute, and is easy to unmount afterwards. Based on the answer provided on Super User: &amp;lt;nowiki&amp;gt;https://superuser.com/a/1548983&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
 &amp;lt;code&amp;gt;mkdir -p ~/tmp/windows10-vm&lt;br /&gt;
 nbdfuse ~/tmp/windows10-vm [ qemu-nbd path_to_disk_image ] &amp;amp;&lt;br /&gt;
 fusermount -u ~/tmp/windows10-vm&amp;lt;/code&amp;gt;&lt;br /&gt;
An alternative is to let QEMU mount the virtual machine disk image with the NBD driver. Enable the nbd kernel module, mount the image, and then mount the partition with flags to make it accessible to other users without superuser privileges. &lt;br /&gt;
&lt;br /&gt;
With fdisk, you can identify the device file pertaining to the partition you want to mount (I&#039;ve used /dev/nbd0p1 for example). The dmask and fmask, are for the octal permission bits of directories and files.&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to run umount when finished.&lt;br /&gt;
&lt;br /&gt;
After running qemu-nbd, it is possible to mount and edit partitions on the numbered &amp;quot;nbd&amp;quot; partitions with gparted (but I recommend making a backup of the disk image on separate media, before resizing/moving partitions in gparted).&lt;br /&gt;
 modprobe nbd&lt;br /&gt;
 qemu-nbd -c /dev/nbd0 &amp;lt;path to VM disk image&amp;gt;&lt;br /&gt;
 fdisk -l /dev/nbd0&lt;br /&gt;
 mount /dev/nbd0p1 /mnt/vhd1 -o dmask=000,fmask=000&lt;br /&gt;
 umount /mnt/vhd1&lt;br /&gt;
&lt;br /&gt;
== NVIDIA ==&lt;br /&gt;
To workaround a bug where the frame rate drops for Mutter and other applications, when they are viewed on an external monitor, boost the memory clock speed with this command below. The two values after lmc are the minimum and maximum memory clock speeds in MHz.&lt;br /&gt;
 sudo nvidia-smi -lmc 2000,6000&lt;br /&gt;
&lt;br /&gt;
== Making Changes to Windows Registry Hive Files ==&lt;br /&gt;
&#039;&#039;&#039;NB: It is recommended that you should make backup copies of any hive files you intend to edit, and store them on a separate partition.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The Windows registry consists of keys and values, belonging to hives. These hives are stored under &amp;lt;code&amp;gt;C:\Windows\system32\config&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
According to Microsoft&#039;s official documentation (https://learn.microsoft.com/en-us/windows/win32/sysinfo/registry-hives), these are the root keys and the hive file names which they correspond to:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Registry hive&lt;br /&gt;
!Supporting files&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_CURRENT_CONFIG&#039;&#039;&#039;&lt;br /&gt;
|System, System.alt, System.log, System.sav&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_CURRENT_USER&#039;&#039;&#039;&lt;br /&gt;
|Ntuser.dat, Ntuser.dat.log&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_LOCAL_MACHINE\SAM&#039;&#039;&#039;&lt;br /&gt;
|Sam, Sam.log, Sam.sav&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_LOCAL_MACHINE\Security&#039;&#039;&#039;&lt;br /&gt;
|Security, Security.log, Security.sav&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_LOCAL_MACHINE\Software&#039;&#039;&#039;&lt;br /&gt;
|Software, Software.log, Software.sav&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_LOCAL_MACHINE\System&#039;&#039;&#039;&lt;br /&gt;
|System, System.alt, System.log, System.sav&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_USERS\.DEFAULT&#039;&#039;&#039;&lt;br /&gt;
|Default, Default.log, Default.sav&lt;br /&gt;
|}I find it useful to browse through sub-keys and values with &amp;lt;code&amp;gt;hivexsh &amp;lt;path to hive&amp;gt;&amp;lt;/code&amp;gt; , then export a key from the hive file (using the file for  HKEY_LOCAL_MACHINE\Software for example): &lt;br /&gt;
 &amp;lt;code&amp;gt;hivexregedit --export ./SOFTWARE Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer &amp;gt; explorer-policies.reg&amp;lt;/code&amp;gt;&lt;br /&gt;
 &amp;lt;code&amp;gt;&lt;br /&gt;
 hivexregedit --merge ./SOFTWARE ./explorer-policies.reg&amp;lt;/code&amp;gt;&lt;br /&gt;
I&#039;ve left out the conversion of the exported registry file from Windows UTF-16 to UTF-8, and back again to UTF-16 before the merge, as I&#039;ve found through testing that this isn&#039;t needed (with hivex version 1.3.23).&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Useful_Commands&amp;diff=80</id>
		<title>GNU Linux/Useful Commands</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Useful_Commands&amp;diff=80"/>
		<updated>2025-12-27T02:38:39Z</updated>

		<summary type="html">&lt;p&gt;Root: /* Copy and Paste Between X11 and Wayland Clipboards */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Information Technology|GNU Linux]]&lt;br /&gt;
&lt;br /&gt;
== Desktop Environments ==&lt;br /&gt;
&lt;br /&gt;
=== Copy and Paste Between X11 and Wayland Clipboards ===&lt;br /&gt;
When running an application inside a root-full X11 session, within XWayland for example, it may not be able to access Wayland&#039;s clipboard directly (pasting doesn&#039;t work). The below commands require packages, which, on ArchLinux are named &amp;quot;xclip&amp;quot; and &amp;quot;wl-clipboard&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
To copy to the X11 clipboard from Wayland&#039;s clipboard use:&lt;br /&gt;
 bash -c &amp;quot;wl-paste | xclip -d &amp;quot;:2&amp;quot; -selection &amp;quot;clipboard&amp;quot;&amp;quot;&lt;br /&gt;
To paste from the X11 clipboard into Wayland&#039;s clipboard (where :2 is replaced with the X11 display name):&lt;br /&gt;
 bash -c &amp;quot;xclip -o -d &amp;quot;:2&amp;quot; -selection &amp;quot;clipboard&amp;quot; | wl-copy&amp;quot;&lt;br /&gt;
I placed the command lines inside a call to bash, as these were added to custom keyboard shortcuts, for my GNOME desktop settings.&lt;br /&gt;
&lt;br /&gt;
== File Conversion ==&lt;br /&gt;
&lt;br /&gt;
=== Batch Convert Man Pages into HTML files ===&lt;br /&gt;
Requires the &amp;lt;code&amp;gt;mandoc&amp;lt;/code&amp;gt; program to be installed.&lt;br /&gt;
 &amp;lt;code&amp;gt;mkdir html &amp;amp;&amp;amp; for x in .; do mandoc -Thtml -O man=./html/%N.%S.html,toc $x &amp;gt; html/$x.html; done&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Virtual Machines ==&lt;br /&gt;
I&#039;ve found this to be more useful than &amp;lt;code&amp;gt;guestmount&amp;lt;/code&amp;gt; (provided by the &amp;lt;code&amp;gt;libguestfs-tools&amp;lt;/code&amp;gt; package for Ubuntu), because it does not require superuser privileges to execute, and is easy to unmount afterwards. Based on the answer provided on Super User: &amp;lt;nowiki&amp;gt;https://superuser.com/a/1548983&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
 &amp;lt;code&amp;gt;mkdir -p ~/tmp/windows10-vm&lt;br /&gt;
 nbdfuse ~/tmp/windows10-vm [ qemu-nbd path_to_disk_image ] &amp;amp;&lt;br /&gt;
 fusermount -u ~/tmp/windows10-vm&amp;lt;/code&amp;gt;&lt;br /&gt;
An alternative is to let QEMU mount the virtual machine disk image with the NBD driver. Enable the nbd kernel module, mount the image, and then mount the partition with flags to make it accessible to other users without superuser privileges. &lt;br /&gt;
&lt;br /&gt;
With fdisk, you can identify the device file pertaining to the partition you want to mount (I&#039;ve used /dev/nbd0p1 for example). The dmask and fmask, are for the octal permission bits of directories and files.&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to run umount when finished.&lt;br /&gt;
 modprobe nbd&lt;br /&gt;
 qemu-nbd --connect=/dev/nbd0 &amp;lt;path to VM disk image&amp;gt;&lt;br /&gt;
 fdisk -l /dev/nbd0&lt;br /&gt;
 mount /dev/nbd0p1 /mnt/vhd1 -o dmask=000,fmask=000&lt;br /&gt;
 umount /mnt/vhd1&lt;br /&gt;
&lt;br /&gt;
== NVIDIA ==&lt;br /&gt;
To workaround a bug where the frame rate drops for Mutter and other applications, when they are viewed on an external monitor, boost the memory clock speed with this command below. The two values after lmc are the minimum and maximum memory clock speeds in MHz.&lt;br /&gt;
 sudo nvidia-smi -lmc 2000,6000&lt;br /&gt;
&lt;br /&gt;
== Making Changes to Windows Registry Hive Files ==&lt;br /&gt;
&#039;&#039;&#039;NB: It is recommended that you should make backup copies of any hive files you intend to edit, and store them on a separate partition.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The Windows registry consists of keys and values, belonging to hives. These hives are stored under &amp;lt;code&amp;gt;C:\Windows\system32\config&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
According to Microsoft&#039;s official documentation (https://learn.microsoft.com/en-us/windows/win32/sysinfo/registry-hives), these are the root keys and the hive file names which they correspond to:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Registry hive&lt;br /&gt;
!Supporting files&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_CURRENT_CONFIG&#039;&#039;&#039;&lt;br /&gt;
|System, System.alt, System.log, System.sav&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_CURRENT_USER&#039;&#039;&#039;&lt;br /&gt;
|Ntuser.dat, Ntuser.dat.log&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_LOCAL_MACHINE\SAM&#039;&#039;&#039;&lt;br /&gt;
|Sam, Sam.log, Sam.sav&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_LOCAL_MACHINE\Security&#039;&#039;&#039;&lt;br /&gt;
|Security, Security.log, Security.sav&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_LOCAL_MACHINE\Software&#039;&#039;&#039;&lt;br /&gt;
|Software, Software.log, Software.sav&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_LOCAL_MACHINE\System&#039;&#039;&#039;&lt;br /&gt;
|System, System.alt, System.log, System.sav&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_USERS\.DEFAULT&#039;&#039;&#039;&lt;br /&gt;
|Default, Default.log, Default.sav&lt;br /&gt;
|}I find it useful to browse through sub-keys and values with &amp;lt;code&amp;gt;hivexsh &amp;lt;path to hive&amp;gt;&amp;lt;/code&amp;gt; , then export a key from the hive file (using the file for  HKEY_LOCAL_MACHINE\Software for example): &lt;br /&gt;
 &amp;lt;code&amp;gt;hivexregedit --export ./SOFTWARE Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer &amp;gt; explorer-policies.reg&amp;lt;/code&amp;gt;&lt;br /&gt;
 &amp;lt;code&amp;gt;&lt;br /&gt;
 hivexregedit --merge ./SOFTWARE ./explorer-policies.reg&amp;lt;/code&amp;gt;&lt;br /&gt;
I&#039;ve left out the conversion of the exported registry file from Windows UTF-16 to UTF-8, and back again to UTF-16 before the merge, as I&#039;ve found through testing that this isn&#039;t needed (with hivex version 1.3.23).&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Useful_Commands&amp;diff=79</id>
		<title>GNU Linux/Useful Commands</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Useful_Commands&amp;diff=79"/>
		<updated>2025-12-21T03:11:53Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Information Technology|GNU Linux]]&lt;br /&gt;
&lt;br /&gt;
== Desktop Environments ==&lt;br /&gt;
&lt;br /&gt;
=== Copy and Paste Between X11 and Wayland Clipboards ===&lt;br /&gt;
When running an application inside a root-full X11 session, within XWayland for example, it may not be able to access Wayland clipboard directly (pasting doesn&#039;t work). The below commands require packages, which, on ArchLinux are named &amp;quot;xclip&amp;quot; and &amp;quot;wl-clipboard&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
To copy to the X11 clipboard from Wayland use:&lt;br /&gt;
 bash -c &amp;quot;wl-paste | xclip -d &amp;quot;:2&amp;quot; -selection &amp;quot;clipboard&amp;quot;&amp;quot;&lt;br /&gt;
To paste from the X11 clipboard into Wayland&#039;s clipboard (where :2 is replaced with the X11 display name):&lt;br /&gt;
 bash -c &amp;quot;xclip -o -d &amp;quot;:2&amp;quot; -selection &amp;quot;clipboard&amp;quot; | wl-copy&amp;quot;&lt;br /&gt;
I placed the command lines inside a call to bash, as these were added to custom keyboard shortcuts, for my GNOME desktop settings.&lt;br /&gt;
&lt;br /&gt;
== File Conversion ==&lt;br /&gt;
&lt;br /&gt;
=== Batch Convert Man Pages into HTML files ===&lt;br /&gt;
Requires the &amp;lt;code&amp;gt;mandoc&amp;lt;/code&amp;gt; program to be installed.&lt;br /&gt;
 &amp;lt;code&amp;gt;mkdir html &amp;amp;&amp;amp; for x in .; do mandoc -Thtml -O man=./html/%N.%S.html,toc $x &amp;gt; html/$x.html; done&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Virtual Machines ==&lt;br /&gt;
I&#039;ve found this to be more useful than &amp;lt;code&amp;gt;guestmount&amp;lt;/code&amp;gt; (provided by the &amp;lt;code&amp;gt;libguestfs-tools&amp;lt;/code&amp;gt; package for Ubuntu), because it does not require superuser privileges to execute, and is easy to unmount afterwards. Based on the answer provided on Super User: &amp;lt;nowiki&amp;gt;https://superuser.com/a/1548983&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
 &amp;lt;code&amp;gt;mkdir -p ~/tmp/windows10-vm&lt;br /&gt;
 nbdfuse ~/tmp/windows10-vm [ qemu-nbd path_to_disk_image ] &amp;amp;&lt;br /&gt;
 fusermount -u ~/tmp/windows10-vm&amp;lt;/code&amp;gt;&lt;br /&gt;
An alternative is to let QEMU mount the virtual machine disk image with the NBD driver. Enable the nbd kernel module, mount the image, and then mount the partition with flags to make it accessible to other users without superuser privileges. &lt;br /&gt;
&lt;br /&gt;
With fdisk, you can identify the device file pertaining to the partition you want to mount (I&#039;ve used /dev/nbd0p1 for example). The dmask and fmask, are for the octal permission bits of directories and files.&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to run umount when finished.&lt;br /&gt;
 modprobe nbd&lt;br /&gt;
 qemu-nbd --connect=/dev/nbd0 &amp;lt;path to VM disk image&amp;gt;&lt;br /&gt;
 fdisk -l /dev/nbd0&lt;br /&gt;
 mount /dev/nbd0p1 /mnt/vhd1 -o dmask=000,fmask=000&lt;br /&gt;
 umount /mnt/vhd1&lt;br /&gt;
&lt;br /&gt;
== NVIDIA ==&lt;br /&gt;
To workaround a bug where the frame rate drops for Mutter and other applications, when they are viewed on an external monitor, boost the memory clock speed with this command below. The two values after lmc are the minimum and maximum memory clock speeds in MHz.&lt;br /&gt;
 sudo nvidia-smi -lmc 2000,6000&lt;br /&gt;
&lt;br /&gt;
== Making Changes to Windows Registry Hive Files ==&lt;br /&gt;
&#039;&#039;&#039;NB: It is recommended that you should make backup copies of any hive files you intend to edit, and store them on a separate partition.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The Windows registry consists of keys and values, belonging to hives. These hives are stored under &amp;lt;code&amp;gt;C:\Windows\system32\config&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
According to Microsoft&#039;s official documentation (https://learn.microsoft.com/en-us/windows/win32/sysinfo/registry-hives), these are the root keys and the hive file names which they correspond to:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Registry hive&lt;br /&gt;
!Supporting files&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_CURRENT_CONFIG&#039;&#039;&#039;&lt;br /&gt;
|System, System.alt, System.log, System.sav&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_CURRENT_USER&#039;&#039;&#039;&lt;br /&gt;
|Ntuser.dat, Ntuser.dat.log&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_LOCAL_MACHINE\SAM&#039;&#039;&#039;&lt;br /&gt;
|Sam, Sam.log, Sam.sav&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_LOCAL_MACHINE\Security&#039;&#039;&#039;&lt;br /&gt;
|Security, Security.log, Security.sav&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_LOCAL_MACHINE\Software&#039;&#039;&#039;&lt;br /&gt;
|Software, Software.log, Software.sav&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_LOCAL_MACHINE\System&#039;&#039;&#039;&lt;br /&gt;
|System, System.alt, System.log, System.sav&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_USERS\.DEFAULT&#039;&#039;&#039;&lt;br /&gt;
|Default, Default.log, Default.sav&lt;br /&gt;
|}I find it useful to browse through sub-keys and values with &amp;lt;code&amp;gt;hivexsh &amp;lt;path to hive&amp;gt;&amp;lt;/code&amp;gt; , then export a key from the hive file (using the file for  HKEY_LOCAL_MACHINE\Software for example): &lt;br /&gt;
 &amp;lt;code&amp;gt;hivexregedit --export ./SOFTWARE Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer &amp;gt; explorer-policies.reg&amp;lt;/code&amp;gt;&lt;br /&gt;
 &amp;lt;code&amp;gt;&lt;br /&gt;
 hivexregedit --merge ./SOFTWARE ./explorer-policies.reg&amp;lt;/code&amp;gt;&lt;br /&gt;
I&#039;ve left out the conversion of the exported registry file from Windows UTF-16 to UTF-8, and back again to UTF-16 before the merge, as I&#039;ve found through testing that this isn&#039;t needed (with hivex version 1.3.23).&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=Common_Algorithms&amp;diff=78</id>
		<title>Common Algorithms</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=Common_Algorithms&amp;diff=78"/>
		<updated>2025-12-06T23:13:51Z</updated>

		<summary type="html">&lt;p&gt;Root: Fixed the Rust version&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Software Development]]&lt;br /&gt;
The code published on this page is provided with the conditions of the MIT license.&lt;br /&gt;
&lt;br /&gt;
== Integer to Words ==&lt;br /&gt;
This converts an integer into English words. Solving this problem was an interesting exercise, as I ended up parsing in 3 stages which were: splitting the digit groups, inserting symbols for base 10 exponents and ampersands after groups of hundreds, and then converting the symbols into words.&lt;br /&gt;
&lt;br /&gt;
I initially started my implementation in Java, then after finishing, moved onto C++. The Rust version was the most difficult, as, of time of writing it, I was still fairly new to the language.&lt;br /&gt;
&lt;br /&gt;
=== Java ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
package com.bgcottrell;&lt;br /&gt;
&lt;br /&gt;
import java.util.*;&lt;br /&gt;
&lt;br /&gt;
public class Main {&lt;br /&gt;
    public static String[] E0Literals = &amp;quot;zero,one,two,three,four,five,six,seven,eight,nine&amp;quot;.split(&amp;quot;,&amp;quot;);&lt;br /&gt;
    public static String[] TNLiterals = &amp;quot;eleven,twelve,thirteen,fourteen,fifteen,sixteen,seventeen,eighteen,nineteen&amp;quot;.split(&amp;quot;,&amp;quot;);&lt;br /&gt;
    public static String[] E1Literals = &amp;quot;ten,twenty,thirty,forty,fifty,sixty,seventy,eighty,ninety&amp;quot;.split(&amp;quot;,&amp;quot;);&lt;br /&gt;
    public static String parseIntString(String strValue)&lt;br /&gt;
    {&lt;br /&gt;
        StringBuilder result = new StringBuilder();&lt;br /&gt;
        Long parsedValue = 0L;&lt;br /&gt;
        //int r = 0;&lt;br /&gt;
        try {&lt;br /&gt;
            parsedValue = Long.parseUnsignedLong(strValue);&lt;br /&gt;
            //r = strValue.length();&lt;br /&gt;
        } catch (NumberFormatException e) {&lt;br /&gt;
            throw new RuntimeException(e);&lt;br /&gt;
        }&lt;br /&gt;
        // Split with commas&lt;br /&gt;
        int numCommas = (int)Math.ceil((double) strValue.length() /6);&lt;br /&gt;
        StringBuilder tokens = new StringBuilder(strValue.length() + numCommas);&lt;br /&gt;
        if (strValue.length() &amp;lt; 4) {&lt;br /&gt;
            for (int i = strValue.length() - 1; i &amp;gt;= 0; i--) {&lt;br /&gt;
                tokens.insert(0, strValue.charAt(i));&lt;br /&gt;
            }&lt;br /&gt;
        } else {&lt;br /&gt;
            for (int i = strValue.length() - 1; i &amp;gt;= 0; i--) {&lt;br /&gt;
                tokens.insert(0, strValue.charAt(i));&lt;br /&gt;
                if ((strValue.length() - i) % 3 == 0 &amp;amp;&amp;amp; (i &amp;gt; 0)) {&lt;br /&gt;
                    tokens.insert(0, &#039;,&#039;);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        System.out.printf(&amp;quot;(%s) &amp;quot;,tokens);&lt;br /&gt;
&lt;br /&gt;
        // Parse, insert exponents, hundred&#039;s joiners&lt;br /&gt;
        String groups[] = tokens.toString().split(&amp;quot;,&amp;quot;);&lt;br /&gt;
        ArrayList&amp;lt;String&amp;gt; parserTokens = new ArrayList&amp;lt;&amp;gt;();&lt;br /&gt;
        for (int gi=0; gi &amp;lt; groups.length; gi++) {&lt;br /&gt;
            switch (groups[gi].length()) {&lt;br /&gt;
                case 3: {&lt;br /&gt;
                    Integer p[] = {&lt;br /&gt;
                            Integer.parseUnsignedInt(String.valueOf(groups[gi].charAt(0))),&lt;br /&gt;
                            Integer.parseUnsignedInt(groups[gi].substring(1)),&lt;br /&gt;
                    };&lt;br /&gt;
                    if (p[0] != 0) {&lt;br /&gt;
                        parserTokens.add(E0Literals[p[0]]);&lt;br /&gt;
                        parserTokens.add(&amp;quot;H&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    if (p[1] != 0 &amp;amp;&amp;amp; p[1] &amp;lt; 10) {&lt;br /&gt;
                        parserTokens.add(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                        parserTokens.add(E0Literals[p[1]]);&lt;br /&gt;
                    } else if (p[1] != 0 &amp;amp;&amp;amp; p[1] &amp;lt; 20) {&lt;br /&gt;
                        parserTokens.add(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                        parserTokens.add(TNLiterals[p[1] - 11]);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        if (groups[gi].charAt(1) != &#039;0&#039;) {&lt;br /&gt;
                            parserTokens.add(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                            parserTokens.add(&lt;br /&gt;
                                    E1Literals[Integer.parseUnsignedInt(String.valueOf(groups[gi].charAt(1))) - 1]&lt;br /&gt;
                            );&lt;br /&gt;
                        }&lt;br /&gt;
                        if (groups[gi].charAt(2) != &#039;0&#039;) {&lt;br /&gt;
                            parserTokens.add(&lt;br /&gt;
                                E0Literals[Integer.parseUnsignedInt(String.valueOf(groups[gi].charAt(2)))]&lt;br /&gt;
                            );&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
                case 2:&lt;br /&gt;
                {&lt;br /&gt;
                    Integer p = Integer.parseUnsignedInt(groups[gi]);&lt;br /&gt;
                    if (p &amp;lt; 10) {&lt;br /&gt;
                        parserTokens.add(E0Literals[p]);&lt;br /&gt;
                    } else if (p &amp;lt; 20) {&lt;br /&gt;
                        parserTokens.add(TNLiterals[p - 11]);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        parserTokens.add(&lt;br /&gt;
                                E1Literals[Integer.parseUnsignedInt(String.valueOf(groups[gi].charAt(0))) - 1]&lt;br /&gt;
                        );&lt;br /&gt;
                        if (groups[gi].charAt(1) != &#039;0&#039;) {&lt;br /&gt;
                            parserTokens.add(&lt;br /&gt;
                                    E0Literals[Integer.parseUnsignedInt(String.valueOf(groups[gi].charAt(1)))]&lt;br /&gt;
                            );&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
                case 1: {&lt;br /&gt;
                    Integer p = Integer.parseUnsignedInt(groups[gi]);&lt;br /&gt;
                    parserTokens.add(E0Literals[p]);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            if (gi == groups.length - 2 &amp;amp;&amp;amp; groups[gi] != &amp;quot;000&amp;quot;) {&lt;br /&gt;
                parserTokens.add(&amp;quot;T&amp;quot;);&lt;br /&gt;
            } else if (gi == groups.length - 3) {&lt;br /&gt;
                parserTokens.add(&amp;quot;M&amp;quot;);&lt;br /&gt;
            } else if (gi == groups.length - 4) {&lt;br /&gt;
                parserTokens.add(&amp;quot;B&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        //System.out.printf(&amp;quot;Parsed: %s&amp;quot;, parserTokens);&lt;br /&gt;
        for (int i =0; i &amp;lt; parserTokens.size() - 1;i++) {&lt;br /&gt;
            switch (parserTokens.get(i)) {&lt;br /&gt;
                case &amp;quot;H&amp;quot;:&lt;br /&gt;
                    result.append(&amp;quot;hundred&amp;quot;);&lt;br /&gt;
                    break;&lt;br /&gt;
                case &amp;quot;T&amp;quot;:&lt;br /&gt;
                    result.append(&amp;quot;thousand&amp;quot;);&lt;br /&gt;
                    break;&lt;br /&gt;
                case &amp;quot;M&amp;quot;:&lt;br /&gt;
                    result.append(&amp;quot;million&amp;quot;);&lt;br /&gt;
                    break;&lt;br /&gt;
                case &amp;quot;B&amp;quot;:&lt;br /&gt;
                    result.append(&amp;quot;billion&amp;quot;);&lt;br /&gt;
                    break;&lt;br /&gt;
                case &amp;quot;&amp;amp;&amp;quot;:&lt;br /&gt;
                    result.append(&amp;quot;and&amp;quot;);&lt;br /&gt;
                    break;&lt;br /&gt;
                default:&lt;br /&gt;
                    result.append(parserTokens.get(i));&lt;br /&gt;
            }&lt;br /&gt;
            result.append(&amp;quot; &amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        switch (parserTokens.getLast()) {&lt;br /&gt;
            case &amp;quot;H&amp;quot;:&lt;br /&gt;
                result.append(&amp;quot;hundred&amp;quot;);&lt;br /&gt;
                break;&lt;br /&gt;
            case &amp;quot;T&amp;quot;:&lt;br /&gt;
                result.append(&amp;quot;thousand&amp;quot;);&lt;br /&gt;
                break;&lt;br /&gt;
            case &amp;quot;M&amp;quot;:&lt;br /&gt;
                result.append(&amp;quot;million&amp;quot;);&lt;br /&gt;
                break;&lt;br /&gt;
            case &amp;quot;B&amp;quot;:&lt;br /&gt;
                result.append(&amp;quot;billion&amp;quot;);&lt;br /&gt;
            case &amp;quot;&amp;amp;&amp;quot;:&lt;br /&gt;
                result.append(&amp;quot;and&amp;quot;);&lt;br /&gt;
            default:&lt;br /&gt;
                result.append(parserTokens.getLast());&lt;br /&gt;
        }&lt;br /&gt;
        return result.toString();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== C++17 ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;cmath&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;iomanip&amp;gt;&lt;br /&gt;
#include &amp;lt;vector&amp;gt;&lt;br /&gt;
#include &amp;lt;ranges&amp;gt;&lt;br /&gt;
#include &amp;lt;string_view&amp;gt;&lt;br /&gt;
#include &amp;lt;algorithm&amp;gt;&lt;br /&gt;
#include &amp;lt;format&amp;gt;&lt;br /&gt;
static string IntToWords(const string&amp;amp; input)&lt;br /&gt;
{&lt;br /&gt;
    static array E0Literals = {&amp;quot;zero&amp;quot;, &amp;quot;one&amp;quot;, &amp;quot;two&amp;quot;, &amp;quot;three&amp;quot;, &amp;quot;four&amp;quot;, &amp;quot;five&amp;quot;, &amp;quot;six&amp;quot;, &amp;quot;seven&amp;quot;, &amp;quot;eight&amp;quot;, &amp;quot;nine&amp;quot;};&lt;br /&gt;
    static array TNLiterals = {&amp;quot;eleven&amp;quot;, &amp;quot;twelve&amp;quot;, &amp;quot;thirteen&amp;quot;, &amp;quot;fourteen&amp;quot;, &amp;quot;fifteen&amp;quot;, &amp;quot;sixteen&amp;quot;, &amp;quot;seventeen&amp;quot;, &amp;quot;eighteen&amp;quot;, &amp;quot;nineteen&amp;quot;};&lt;br /&gt;
    static array E1Literals = {&amp;quot;ten&amp;quot;, &amp;quot;twenty&amp;quot;, &amp;quot;thirty&amp;quot;, &amp;quot;forty&amp;quot;, &amp;quot;fifty&amp;quot;, &amp;quot;sixty&amp;quot;, &amp;quot;seventy&amp;quot;, &amp;quot;eighty&amp;quot;, &amp;quot;ninety&amp;quot;};&lt;br /&gt;
    string result;&lt;br /&gt;
    try {&lt;br /&gt;
        ulong parsedValue = stoul(input);&lt;br /&gt;
    } catch (const exception&amp;amp; ex) {&lt;br /&gt;
        return &amp;quot;invalid&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    // Split with commas, make it easier to parse&lt;br /&gt;
    const auto numCommas = int(ceil(input.length()/6));&lt;br /&gt;
    string tokens;&lt;br /&gt;
    tokens.reserve(input.length()+numCommas);&lt;br /&gt;
    if (input.length() &amp;lt; 4) {&lt;br /&gt;
        for (int i=input.length()-1;i&amp;gt;=0;i--) {&lt;br /&gt;
            tokens.insert(tokens.begin(), input.at(i));&lt;br /&gt;
        }&lt;br /&gt;
    } else {&lt;br /&gt;
        for (int i=input.length()-1;i&amp;gt;=0;i--) {&lt;br /&gt;
            tokens.insert(tokens.begin(),input.at(i));&lt;br /&gt;
            if ((input.length() -i) % 3 == 0) {&lt;br /&gt;
                tokens.insert(tokens.begin(),&#039;,&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    // Parse, insert exponents, joiners&lt;br /&gt;
    vector&amp;lt;string&amp;gt; groups = split(tokens, &amp;quot;,&amp;quot;);&lt;br /&gt;
    vector&amp;lt;string&amp;gt; parserTokens;&lt;br /&gt;
    parserTokens.reserve(input.length()*2);&lt;br /&gt;
    for (size_t gi=0; gi != groups.size(); gi++) {&lt;br /&gt;
        switch (groups[gi].length()) {&lt;br /&gt;
        case 3:&lt;br /&gt;
        {&lt;br /&gt;
            vector&amp;lt;int&amp;gt; p = {&lt;br /&gt;
                stoi(groups[gi].substr(0,1)),&lt;br /&gt;
                stoi(groups[gi].substr(1))&lt;br /&gt;
            };&lt;br /&gt;
            if (p[0] != 0) {&lt;br /&gt;
                parserTokens.push_back(E0Literals[p[0]]);&lt;br /&gt;
                parserTokens.push_back(&amp;quot;H&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            if (p[1] != 0 &amp;amp;&amp;amp; p[1] &amp;lt; 10) {&lt;br /&gt;
                parserTokens.push_back(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                parserTokens.push_back(E0Literals[p[1]]);&lt;br /&gt;
            } else if (p[1] != 0 &amp;amp;&amp;amp; p[1] &amp;lt; 20) {&lt;br /&gt;
                parserTokens.push_back(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                parserTokens.push_back(TNLiterals[p[1]-11]);&lt;br /&gt;
            } else {&lt;br /&gt;
                if (groups[gi].at(1) != &#039;0&#039;) {&lt;br /&gt;
                    parserTokens.push_back(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                    parserTokens.push_back(&lt;br /&gt;
                        E1Literals[stoi(groups[gi].substr(1,1))-1]&lt;br /&gt;
                    );&lt;br /&gt;
                }&lt;br /&gt;
                if (groups[gi].at(2) != &#039;0&#039;) {&lt;br /&gt;
                    parserTokens.push_back(&lt;br /&gt;
                        E0Literals[stoi(groups[gi].substr(2,1))]&lt;br /&gt;
                    );&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        case 2:&lt;br /&gt;
        {&lt;br /&gt;
            int p = stoi(groups[gi]);&lt;br /&gt;
            if (p &amp;lt; 10) {&lt;br /&gt;
                parserTokens.push_back(E0Literals[p]);&lt;br /&gt;
            } else if (p &amp;lt; 20) {&lt;br /&gt;
                parserTokens.push_back(TNLiterals[p-11]);&lt;br /&gt;
            } else {&lt;br /&gt;
                parserTokens.push_back(&lt;br /&gt;
                    E1Literals[stoi(groups[gi].substr(0,1))-1]&lt;br /&gt;
                );&lt;br /&gt;
                if (groups[gi].at(1) != &#039;0&#039;) {&lt;br /&gt;
                    parserTokens.push_back(&lt;br /&gt;
                        E0Literals[stoi(groups[gi].substr(1,1))]&lt;br /&gt;
                    );&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        case 1:&lt;br /&gt;
        {&lt;br /&gt;
            int p = stoi(groups[gi]);&lt;br /&gt;
            parserTokens.push_back(E0Literals[p]);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        } /* switch */&lt;br /&gt;
        if (gi == groups.size() - 2 &amp;amp;&amp;amp; groups[gi] != &amp;quot;000&amp;quot;) {&lt;br /&gt;
            parserTokens.push_back(&amp;quot;T&amp;quot;);&lt;br /&gt;
        } else if (gi == groups.size() - 3) {&lt;br /&gt;
            parserTokens.push_back(&amp;quot;M&amp;quot;);&lt;br /&gt;
        } else if (gi == groups.size() - 4) {&lt;br /&gt;
            parserTokens.push_back(&amp;quot;B&amp;quot;);&lt;br /&gt;
        } else if (gi == groups.size() - 5) {&lt;br /&gt;
            parserTokens.push_back(&amp;quot;Tr&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        } /* for */&lt;br /&gt;
        for (int i=0; i &amp;lt; parserTokens.size() - 1; i++) {&lt;br /&gt;
            string s = parserTokens.at(i);&lt;br /&gt;
            if (s == &amp;quot;H&amp;quot;) {&lt;br /&gt;
                result.append(&amp;quot;hundred&amp;quot;);&lt;br /&gt;
            } else if (s == &amp;quot;T&amp;quot;) {&lt;br /&gt;
                result.append(&amp;quot;thousand&amp;quot;);&lt;br /&gt;
            } else if (s == &amp;quot;M&amp;quot;) {&lt;br /&gt;
                result.append(&amp;quot;million&amp;quot;);&lt;br /&gt;
            } else if (s == &amp;quot;B&amp;quot;) {&lt;br /&gt;
                result.append(&amp;quot;billion&amp;quot;);&lt;br /&gt;
            } else if (s == &amp;quot;Tr&amp;quot;) {&lt;br /&gt;
                result.append(&amp;quot;trillion&amp;quot;);&lt;br /&gt;
            } else if (s == &amp;quot;&amp;amp;&amp;quot;) {&lt;br /&gt;
                result.append(&amp;quot;and&amp;quot;);&lt;br /&gt;
            } else {&lt;br /&gt;
                result.append(s);&lt;br /&gt;
            }&lt;br /&gt;
            result.append(&amp;quot; &amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        auto s = parserTokens.back();&lt;br /&gt;
        if (s == &amp;quot;H&amp;quot;) {&lt;br /&gt;
            result.append(&amp;quot;hundred&amp;quot;);&lt;br /&gt;
        } else if (s == &amp;quot;T&amp;quot;) {&lt;br /&gt;
            result.append(&amp;quot;thousand&amp;quot;);&lt;br /&gt;
        } else if (s == &amp;quot;M&amp;quot;) {&lt;br /&gt;
            result.append(&amp;quot;million&amp;quot;);&lt;br /&gt;
        } else if (s == &amp;quot;B&amp;quot;) {&lt;br /&gt;
            result.append(&amp;quot;billion&amp;quot;);&lt;br /&gt;
        } else if (s == &amp;quot;Tr&amp;quot;) {&lt;br /&gt;
            result.append(&amp;quot;trillion&amp;quot;);&lt;br /&gt;
        } else if (s == &amp;quot;&amp;amp;&amp;quot;) {&lt;br /&gt;
            result.append(&amp;quot;and&amp;quot;);&lt;br /&gt;
        } else {&lt;br /&gt;
            result.append(s);&lt;br /&gt;
        }&lt;br /&gt;
    return result;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rust ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;rust&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
use std::iter::Iterator;&lt;br /&gt;
use std::ops::Deref;&lt;br /&gt;
use std::str::FromStr;&lt;br /&gt;
struct IntToWords;&lt;br /&gt;
impl IntToWords&lt;br /&gt;
{&lt;br /&gt;
    // Using Option, because I cannot figure out how to return generic errors&lt;br /&gt;
    pub fn parse_value(&amp;amp;self, input: &amp;amp;str) -&amp;gt; Option&amp;lt;String&amp;gt;&lt;br /&gt;
    {&lt;br /&gt;
        let E0Literals: Vec&amp;lt;&amp;amp;&#039;static str&amp;gt; = &amp;quot;zero,one,two,three,four,five,six,seven,eight,nine,ten&amp;quot;.split(&#039;,&#039;).collect();&lt;br /&gt;
        let TNLiterals: Vec&amp;lt;&amp;amp;&#039;static str&amp;gt; = &amp;quot;eleven,twelve,thirteen,fourteen,fifteen,sixteen,seventeen,eighteen,nineteen&amp;quot;.split(&#039;,&#039;).collect();&lt;br /&gt;
        let E1Literals: Vec&amp;lt;&amp;amp;&#039;static str&amp;gt; = &amp;quot;ten,twenty,thirty,forty,fifty,sixty,seventy,eighty,ninety&amp;quot;.split(&#039;,&#039;).collect();&lt;br /&gt;
        let mut result: String = String::from(&amp;quot;&amp;quot;);&lt;br /&gt;
        let parsed_value = u64::from_str(input);&lt;br /&gt;
        if parsed_value.is_err() {&lt;br /&gt;
            return Some(String::from(&amp;quot;invalid&amp;quot;));&lt;br /&gt;
        }&lt;br /&gt;
        let num_commas = (input.len() as f32/6.0).ceil();&lt;br /&gt;
        // Split into digit groups&lt;br /&gt;
        let mut tokens: String = &amp;quot;&amp;quot;.to_string();&lt;br /&gt;
        tokens.reserve(input.len()+num_commas as usize);&lt;br /&gt;
        if input.len() &amp;lt; 4 {&lt;br /&gt;
            let mut i = input.len()-1;&lt;br /&gt;
            loop {&lt;br /&gt;
                tokens.insert(0, input.chars().nth(i).unwrap());&lt;br /&gt;
                if i &amp;gt; 0 { i -= 1; } else { break; }&lt;br /&gt;
            }&lt;br /&gt;
        } else {&lt;br /&gt;
            let mut i = input.len()-1;&lt;br /&gt;
            loop {&lt;br /&gt;
                tokens.insert(0,input.chars().nth(i).unwrap());&lt;br /&gt;
                if i &amp;gt; 0 &amp;amp;&amp;amp; (input.len()-i) % 3 == 0 {&lt;br /&gt;
                    tokens.insert(0,&#039;,&#039;);&lt;br /&gt;
                }&lt;br /&gt;
                if i &amp;gt; 0 { i -= 1; } else { break; }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        // Parse the digit groups&lt;br /&gt;
        let groups : Vec&amp;lt;&amp;amp;str&amp;gt; = tokens.split(&#039;,&#039;).collect();&lt;br /&gt;
        let mut parser_tokens:Vec&amp;lt;&amp;amp;str&amp;gt; = Vec::new();&lt;br /&gt;
        for gi in 0..groups.len() {&lt;br /&gt;
            match groups[gi].len() {&lt;br /&gt;
                3 =&amp;gt; {&lt;br /&gt;
                    let p = [&lt;br /&gt;
                        usize::from_str(&amp;amp;groups[gi].chars().as_str()[0..1]).unwrap(),&lt;br /&gt;
                        usize::from_str(&amp;amp;groups[gi].chars().as_str()[1..]).unwrap()&lt;br /&gt;
                    ];&lt;br /&gt;
                    let p1 = (p[1] as f32/10_f32).floor() as u32;&lt;br /&gt;
                    let p2 = p[1] as u32 - (p1 as u32 * 10);&lt;br /&gt;
                    if p[0] != 0 {&lt;br /&gt;
                        parser_tokens.push(E0Literals[p[0]]);&lt;br /&gt;
                        parser_tokens.push(&amp;quot;H&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    if p[1] != 0 &amp;amp;&amp;amp; p[1] &amp;lt;= 10 {&lt;br /&gt;
                        parser_tokens.push(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                        parser_tokens.push(E0Literals[p[1]]);&lt;br /&gt;
                    } else if p[1] != 0 &amp;amp;&amp;amp; p[1] &amp;lt; 20 {&lt;br /&gt;
                        parser_tokens.push(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                        parser_tokens.push(TNLiterals[p[1] - 11]);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        if groups[gi].chars().nth(1).unwrap() != &#039;0&#039; {&lt;br /&gt;
                            parser_tokens.push(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                            parser_tokens.push(&lt;br /&gt;
                                E1Literals[p1 as usize - 1]&lt;br /&gt;
                            );&lt;br /&gt;
                        }&lt;br /&gt;
                        if groups[gi].chars().nth(2).unwrap() != &#039;0&#039; {&lt;br /&gt;
                            parser_tokens.push(&lt;br /&gt;
                                E0Literals[p2 as usize]&lt;br /&gt;
                            );&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                2 =&amp;gt; {&lt;br /&gt;
                    let p = usize::from_str(&amp;amp;groups[gi]).unwrap();&lt;br /&gt;
                    let p1 = (p as f32/10_f32).floor() as u32;&lt;br /&gt;
                    let p2 = p as u32 - (p1 * 10);&lt;br /&gt;
                    if p &amp;lt;= 10 {&lt;br /&gt;
                        parser_tokens.push(E0Literals[p]);&lt;br /&gt;
                    } else if p &amp;lt; 20 {&lt;br /&gt;
                        parser_tokens.push(TNLiterals[p - 11]);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        parser_tokens.push(&lt;br /&gt;
                            E1Literals[p1 as usize-1]&lt;br /&gt;
                        );&lt;br /&gt;
                        if groups[gi].chars().nth(1).unwrap() != &#039;0&#039; {&lt;br /&gt;
                            parser_tokens.push(&lt;br /&gt;
                                E0Literals[p2 as usize]&lt;br /&gt;
                            );&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                1 =&amp;gt; {&lt;br /&gt;
                    let p = usize::from_str(groups[gi]).unwrap();&lt;br /&gt;
                    parser_tokens.push(E0Literals[p]);&lt;br /&gt;
                }&lt;br /&gt;
                _ =&amp;gt; {}&lt;br /&gt;
            } /* match */&lt;br /&gt;
            if groups.len() &amp;gt;= 2 &amp;amp;&amp;amp; gi == groups.len() - 2 &amp;amp;&amp;amp; groups[gi] != &amp;quot;000&amp;quot; {&lt;br /&gt;
                parser_tokens.push(&amp;quot;T&amp;quot;);&lt;br /&gt;
            } else if groups.len() &amp;gt;= 3 &amp;amp;&amp;amp; gi == groups.len() - 3 {&lt;br /&gt;
                parser_tokens.push(&amp;quot;M&amp;quot;);&lt;br /&gt;
            } else if groups.len() &amp;gt;= 4 &amp;amp;&amp;amp; gi == groups.len() - 4 {&lt;br /&gt;
                parser_tokens.push(&amp;quot;B&amp;quot;);&lt;br /&gt;
            } else if groups.len() &amp;gt;= 5 &amp;amp;&amp;amp; gi == groups.len() - 5 {&lt;br /&gt;
                parser_tokens.push(&amp;quot;Tr&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        // Convert tokens to words&lt;br /&gt;
        for i in 0..parser_tokens.len() {&lt;br /&gt;
            let s = parser_tokens[i];&lt;br /&gt;
            result.push_str(match s {&lt;br /&gt;
                &amp;quot;H&amp;quot; =&amp;gt; &amp;quot;hundred&amp;quot;,&lt;br /&gt;
                &amp;quot;T&amp;quot; =&amp;gt; &amp;quot;thousand&amp;quot;,&lt;br /&gt;
                &amp;quot;M&amp;quot; =&amp;gt; &amp;quot;million&amp;quot;,&lt;br /&gt;
                &amp;quot;B&amp;quot; =&amp;gt; &amp;quot;billion&amp;quot;,&lt;br /&gt;
                &amp;quot;Tr&amp;quot; =&amp;gt; &amp;quot;trillion&amp;quot;,&lt;br /&gt;
                &amp;quot;&amp;amp;&amp;quot; =&amp;gt; &amp;quot;and&amp;quot;,&lt;br /&gt;
                _ =&amp;gt; s&lt;br /&gt;
            });&lt;br /&gt;
            result.push_str(&amp;quot; &amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        Some(result)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pub fn main() {&lt;br /&gt;
    let instance: IntToWords = IntToWords { };&lt;br /&gt;
    let test_numbers: Vec&amp;lt;&amp;amp;str&amp;gt; = Vec::from([&amp;quot;1001&amp;quot;,&amp;quot;10101010&amp;quot;,&amp;quot;1100001&amp;quot;,&amp;quot;1110001&amp;quot;,&amp;quot;26&amp;quot;,&amp;quot;13&amp;quot;,&amp;quot;210&amp;quot;]);&lt;br /&gt;
    for n in test_numbers {&lt;br /&gt;
        println!(&amp;quot;{:-15}: {}&amp;quot;, n, instance.parse_value(n).unwrap());&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Workarounds&amp;diff=77</id>
		<title>GNU Linux/Workarounds</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Workarounds&amp;diff=77"/>
		<updated>2025-04-10T00:25:33Z</updated>

		<summary type="html">&lt;p&gt;Root: /* GPU&amp;#039;s */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Information Technology|GNU Linux]]&lt;br /&gt;
A lot of distributions come fairly close to being perfect, but sometimes default configurations or behaviors need to be adjusted to work for certain scenarios. Please consult the help material that accompanies the tools referenced below, if you need a better understanding of their functionalities or behaviors, and whether or not these fixes are appropriate for your use cases.&lt;br /&gt;
&lt;br /&gt;
== Networking ==&lt;br /&gt;
&lt;br /&gt;
=== WiFi Hotspot Issues ===&lt;br /&gt;
&lt;br /&gt;
==== Clients Unable to Get Internet Access ====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;I recommend just having iptables as a firewall alone, and not in combination with, other firewalls. After writing this, I found that no rules in iptables chains were necessary for my client to connect to my WiFi hotspot. Add the rules below, as a last resort.&amp;lt;/blockquote&amp;gt;In my case, after installing Docker on endeavourOS, I found that my hotspot could be connected to, but, the client was unable to obtain an IP address. I was using GNOME&#039;s settings applet, which is a wrapper for NetworkManager.&lt;br /&gt;
&lt;br /&gt;
Luckily, iptables, the firewall built into Linux, can be used. Based on hints provided by (https://wiki.archlinux.org/title/Internet_sharing#With_iptables)[https://wiki.archlinux.org/title/Internet_sharing#With_iptables], I could add a link level packet filter with NAT, using something similar to the these commands (with superuser privileges):&lt;br /&gt;
&lt;br /&gt;
 iptables -t nat -A POSTROUTING -o &amp;lt;ethernet interface name&amp;gt; -j MASQUERADE&lt;br /&gt;
 iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT&lt;br /&gt;
 iptables -A FORWARD -i &amp;lt;wifi adapter name&amp;gt; -o &amp;lt;ethernet interface name&amp;gt; -j ACCEPT&lt;br /&gt;
&lt;br /&gt;
Note: Network interfaces can be listed with the &amp;quot;ifconfig&amp;quot; program.&lt;br /&gt;
&lt;br /&gt;
If clients are still unable to gain internet access after connecting to the hotspot, try disabling firewalld (this is because, as a RedHat blog article points out, it can conflict with iptables: https://www.redhat.com/en/blog/iptables). &lt;br /&gt;
&lt;br /&gt;
== GPU&#039;s ==&lt;br /&gt;
&lt;br /&gt;
=== Prioritize the Usage of NVIDIA&#039;s OpenGL Library ===&lt;br /&gt;
Set these environment variables, either by prefixing export, or by prepending the following, before the path to a program:&lt;br /&gt;
 __NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia&lt;br /&gt;
&lt;br /&gt;
=== Wayland User Experience Fixes ===&lt;br /&gt;
==== Lag with NVIDIA GPU&#039;s ====&lt;br /&gt;
If you have an AMD graphics card, either integrated or dedicated, you will likely be accustomed to having a better user experience than those with NVIDIA graphics cards.&lt;br /&gt;
&lt;br /&gt;
Wayland works pretty well, but memory and other clock settings stay at too low of a frequency, causing lag. This is noticeable with the GNOME desktop shell. I use this code below to increase the minimum clock speeds on my dedicated GPU.&lt;br /&gt;
 sudo nvidia-smi -pm 1&lt;br /&gt;
 sudo nvidia-smi -lmc 1000,6000&lt;br /&gt;
 sudo nvidia-smi -lgc 1000,2000&lt;br /&gt;
The first command enables the persistence mode daemon, which keeps the kernel mode driver running (even when no other application is actively using it), the second locks the memory clock between 1000 and 6000 MHz, and the last, locks the graphics clock to be between 1000 and 2000 MHz. The command line arguments cannot be combined into one invocation, as nvidia-smi will not allow it.&lt;br /&gt;
&lt;br /&gt;
I&#039;ve found it useful to have a systemd service to do this automatically, when the system starts. I have written a file located here: &#039;&#039;&#039;/etc/systemd/system/nvidia-fix-clocks.service:&#039;&#039;&#039;&lt;br /&gt;
 [Unit]&lt;br /&gt;
 Description=Boost NVIDIA GPU memory and graphics clock speeds&lt;br /&gt;
 &lt;br /&gt;
 [Service]&lt;br /&gt;
 Type=oneshot&lt;br /&gt;
 ExecStart=/opt/ScriptFixes/nv_fix_clocks.sh&lt;br /&gt;
 &lt;br /&gt;
 [Install]&lt;br /&gt;
 WantedBy=multi-user.target&lt;br /&gt;
Don&#039;t forget to reload systemd&#039;s daemon with &#039;&#039;&#039;systemctl reload-daemon&#039;&#039;&#039;, and to enable the service with &#039;&#039;&#039;systemctl enable nvidia-fix-clocks.service&#039;&#039;&#039;. The changes will apply on the next reboot.&lt;br /&gt;
&lt;br /&gt;
==== OpenGL/X11 Application Not Running With a Dedicated NVIDIA GPU ====&lt;br /&gt;
I encountered this issue when running &#039;&#039;Freecad,&#039;&#039; which, in my case, could not use my dedicated GPU due to initialization issues with the OpenGL Extension for X11 (GLX). I use this code below, within a script, to ensure Freecad&#039;s rendering path goes a different way:&lt;br /&gt;
 Xwayland -decorate -geometry 1920x1080 :2 &amp;amp;&lt;br /&gt;
 QT_QPA_PLATFORM=xcb prime-run freecad -display :2&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=Common_Algorithms&amp;diff=76</id>
		<title>Common Algorithms</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=Common_Algorithms&amp;diff=76"/>
		<updated>2025-04-09T09:59:07Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Software Development]]&lt;br /&gt;
The code published on this page is provided with the conditions of the MIT license.&lt;br /&gt;
&lt;br /&gt;
== Integer to Words ==&lt;br /&gt;
This converts an integer into English words. Solving this problem was an interesting exercise, as I ended up parsing in 3 stages which were: splitting the digit groups, inserting symbols for base 10 exponents and ampersands after groups of hundreds, and then converting the symbols into words.&lt;br /&gt;
&lt;br /&gt;
I initially started my implementation in Java, then after finishing, moved onto C++. The Rust version was the most difficult, as, of time of writing it, I was still fairly new to the language.&lt;br /&gt;
&lt;br /&gt;
=== Java ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
package com.bgcottrell;&lt;br /&gt;
&lt;br /&gt;
import java.util.*;&lt;br /&gt;
&lt;br /&gt;
public class Main {&lt;br /&gt;
    public static String[] E0Literals = &amp;quot;zero,one,two,three,four,five,six,seven,eight,nine&amp;quot;.split(&amp;quot;,&amp;quot;);&lt;br /&gt;
    public static String[] TNLiterals = &amp;quot;eleven,twelve,thirteen,fourteen,fifteen,sixteen,seventeen,eighteen,nineteen&amp;quot;.split(&amp;quot;,&amp;quot;);&lt;br /&gt;
    public static String[] E1Literals = &amp;quot;ten,twenty,thirty,forty,fifty,sixty,seventy,eighty,ninety&amp;quot;.split(&amp;quot;,&amp;quot;);&lt;br /&gt;
    public static String parseIntString(String strValue)&lt;br /&gt;
    {&lt;br /&gt;
        StringBuilder result = new StringBuilder();&lt;br /&gt;
        Long parsedValue = 0L;&lt;br /&gt;
        //int r = 0;&lt;br /&gt;
        try {&lt;br /&gt;
            parsedValue = Long.parseUnsignedLong(strValue);&lt;br /&gt;
            //r = strValue.length();&lt;br /&gt;
        } catch (NumberFormatException e) {&lt;br /&gt;
            throw new RuntimeException(e);&lt;br /&gt;
        }&lt;br /&gt;
        // Split with commas&lt;br /&gt;
        int numCommas = (int)Math.ceil((double) strValue.length() /6);&lt;br /&gt;
        StringBuilder tokens = new StringBuilder(strValue.length() + numCommas);&lt;br /&gt;
        if (strValue.length() &amp;lt; 4) {&lt;br /&gt;
            for (int i = strValue.length() - 1; i &amp;gt;= 0; i--) {&lt;br /&gt;
                tokens.insert(0, strValue.charAt(i));&lt;br /&gt;
            }&lt;br /&gt;
        } else {&lt;br /&gt;
            for (int i = strValue.length() - 1; i &amp;gt;= 0; i--) {&lt;br /&gt;
                tokens.insert(0, strValue.charAt(i));&lt;br /&gt;
                if ((strValue.length() - i) % 3 == 0 &amp;amp;&amp;amp; (i &amp;gt; 0)) {&lt;br /&gt;
                    tokens.insert(0, &#039;,&#039;);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        System.out.printf(&amp;quot;(%s) &amp;quot;,tokens);&lt;br /&gt;
&lt;br /&gt;
        // Parse, insert exponents, hundred&#039;s joiners&lt;br /&gt;
        String groups[] = tokens.toString().split(&amp;quot;,&amp;quot;);&lt;br /&gt;
        ArrayList&amp;lt;String&amp;gt; parserTokens = new ArrayList&amp;lt;&amp;gt;();&lt;br /&gt;
        for (int gi=0; gi &amp;lt; groups.length; gi++) {&lt;br /&gt;
            switch (groups[gi].length()) {&lt;br /&gt;
                case 3: {&lt;br /&gt;
                    Integer p[] = {&lt;br /&gt;
                            Integer.parseUnsignedInt(String.valueOf(groups[gi].charAt(0))),&lt;br /&gt;
                            Integer.parseUnsignedInt(groups[gi].substring(1)),&lt;br /&gt;
                    };&lt;br /&gt;
                    if (p[0] != 0) {&lt;br /&gt;
                        parserTokens.add(E0Literals[p[0]]);&lt;br /&gt;
                        parserTokens.add(&amp;quot;H&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    if (p[1] != 0 &amp;amp;&amp;amp; p[1] &amp;lt; 10) {&lt;br /&gt;
                        parserTokens.add(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                        parserTokens.add(E0Literals[p[1]]);&lt;br /&gt;
                    } else if (p[1] != 0 &amp;amp;&amp;amp; p[1] &amp;lt; 20) {&lt;br /&gt;
                        parserTokens.add(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                        parserTokens.add(TNLiterals[p[1] - 11]);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        if (groups[gi].charAt(1) != &#039;0&#039;) {&lt;br /&gt;
                            parserTokens.add(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                            parserTokens.add(&lt;br /&gt;
                                    E1Literals[Integer.parseUnsignedInt(String.valueOf(groups[gi].charAt(1))) - 1]&lt;br /&gt;
                            );&lt;br /&gt;
                        }&lt;br /&gt;
                        if (groups[gi].charAt(2) != &#039;0&#039;) {&lt;br /&gt;
                            parserTokens.add(&lt;br /&gt;
                                E0Literals[Integer.parseUnsignedInt(String.valueOf(groups[gi].charAt(2)))]&lt;br /&gt;
                            );&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
                case 2:&lt;br /&gt;
                {&lt;br /&gt;
                    Integer p = Integer.parseUnsignedInt(groups[gi]);&lt;br /&gt;
                    if (p &amp;lt; 10) {&lt;br /&gt;
                        parserTokens.add(E0Literals[p]);&lt;br /&gt;
                    } else if (p &amp;lt; 20) {&lt;br /&gt;
                        parserTokens.add(TNLiterals[p - 11]);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        parserTokens.add(&lt;br /&gt;
                                E1Literals[Integer.parseUnsignedInt(String.valueOf(groups[gi].charAt(0))) - 1]&lt;br /&gt;
                        );&lt;br /&gt;
                        if (groups[gi].charAt(1) != &#039;0&#039;) {&lt;br /&gt;
                            parserTokens.add(&lt;br /&gt;
                                    E0Literals[Integer.parseUnsignedInt(String.valueOf(groups[gi].charAt(1)))]&lt;br /&gt;
                            );&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
                case 1: {&lt;br /&gt;
                    Integer p = Integer.parseUnsignedInt(groups[gi]);&lt;br /&gt;
                    parserTokens.add(E0Literals[p]);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            if (gi == groups.length - 2 &amp;amp;&amp;amp; groups[gi] != &amp;quot;000&amp;quot;) {&lt;br /&gt;
                parserTokens.add(&amp;quot;T&amp;quot;);&lt;br /&gt;
            } else if (gi == groups.length - 3) {&lt;br /&gt;
                parserTokens.add(&amp;quot;M&amp;quot;);&lt;br /&gt;
            } else if (gi == groups.length - 4) {&lt;br /&gt;
                parserTokens.add(&amp;quot;B&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        //System.out.printf(&amp;quot;Parsed: %s&amp;quot;, parserTokens);&lt;br /&gt;
        for (int i =0; i &amp;lt; parserTokens.size() - 1;i++) {&lt;br /&gt;
            switch (parserTokens.get(i)) {&lt;br /&gt;
                case &amp;quot;H&amp;quot;:&lt;br /&gt;
                    result.append(&amp;quot;hundred&amp;quot;);&lt;br /&gt;
                    break;&lt;br /&gt;
                case &amp;quot;T&amp;quot;:&lt;br /&gt;
                    result.append(&amp;quot;thousand&amp;quot;);&lt;br /&gt;
                    break;&lt;br /&gt;
                case &amp;quot;M&amp;quot;:&lt;br /&gt;
                    result.append(&amp;quot;million&amp;quot;);&lt;br /&gt;
                    break;&lt;br /&gt;
                case &amp;quot;B&amp;quot;:&lt;br /&gt;
                    result.append(&amp;quot;billion&amp;quot;);&lt;br /&gt;
                    break;&lt;br /&gt;
                case &amp;quot;&amp;amp;&amp;quot;:&lt;br /&gt;
                    result.append(&amp;quot;and&amp;quot;);&lt;br /&gt;
                    break;&lt;br /&gt;
                default:&lt;br /&gt;
                    result.append(parserTokens.get(i));&lt;br /&gt;
            }&lt;br /&gt;
            result.append(&amp;quot; &amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        switch (parserTokens.getLast()) {&lt;br /&gt;
            case &amp;quot;H&amp;quot;:&lt;br /&gt;
                result.append(&amp;quot;hundred&amp;quot;);&lt;br /&gt;
                break;&lt;br /&gt;
            case &amp;quot;T&amp;quot;:&lt;br /&gt;
                result.append(&amp;quot;thousand&amp;quot;);&lt;br /&gt;
                break;&lt;br /&gt;
            case &amp;quot;M&amp;quot;:&lt;br /&gt;
                result.append(&amp;quot;million&amp;quot;);&lt;br /&gt;
                break;&lt;br /&gt;
            case &amp;quot;B&amp;quot;:&lt;br /&gt;
                result.append(&amp;quot;billion&amp;quot;);&lt;br /&gt;
            case &amp;quot;&amp;amp;&amp;quot;:&lt;br /&gt;
                result.append(&amp;quot;and&amp;quot;);&lt;br /&gt;
            default:&lt;br /&gt;
                result.append(parserTokens.getLast());&lt;br /&gt;
        }&lt;br /&gt;
        return result.toString();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== C++17 ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;cmath&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;iomanip&amp;gt;&lt;br /&gt;
#include &amp;lt;vector&amp;gt;&lt;br /&gt;
#include &amp;lt;ranges&amp;gt;&lt;br /&gt;
#include &amp;lt;string_view&amp;gt;&lt;br /&gt;
#include &amp;lt;algorithm&amp;gt;&lt;br /&gt;
#include &amp;lt;format&amp;gt;&lt;br /&gt;
static string IntToWords(const string&amp;amp; input)&lt;br /&gt;
{&lt;br /&gt;
    static array E0Literals = {&amp;quot;zero&amp;quot;, &amp;quot;one&amp;quot;, &amp;quot;two&amp;quot;, &amp;quot;three&amp;quot;, &amp;quot;four&amp;quot;, &amp;quot;five&amp;quot;, &amp;quot;six&amp;quot;, &amp;quot;seven&amp;quot;, &amp;quot;eight&amp;quot;, &amp;quot;nine&amp;quot;};&lt;br /&gt;
    static array TNLiterals = {&amp;quot;eleven&amp;quot;, &amp;quot;twelve&amp;quot;, &amp;quot;thirteen&amp;quot;, &amp;quot;fourteen&amp;quot;, &amp;quot;fifteen&amp;quot;, &amp;quot;sixteen&amp;quot;, &amp;quot;seventeen&amp;quot;, &amp;quot;eighteen&amp;quot;, &amp;quot;nineteen&amp;quot;};&lt;br /&gt;
    static array E1Literals = {&amp;quot;ten&amp;quot;, &amp;quot;twenty&amp;quot;, &amp;quot;thirty&amp;quot;, &amp;quot;forty&amp;quot;, &amp;quot;fifty&amp;quot;, &amp;quot;sixty&amp;quot;, &amp;quot;seventy&amp;quot;, &amp;quot;eighty&amp;quot;, &amp;quot;ninety&amp;quot;};&lt;br /&gt;
    string result;&lt;br /&gt;
    try {&lt;br /&gt;
        ulong parsedValue = stoul(input);&lt;br /&gt;
    } catch (const exception&amp;amp; ex) {&lt;br /&gt;
        return &amp;quot;invalid&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    // Split with commas, make it easier to parse&lt;br /&gt;
    const auto numCommas = int(ceil(input.length()/6));&lt;br /&gt;
    string tokens;&lt;br /&gt;
    tokens.reserve(input.length()+numCommas);&lt;br /&gt;
    if (input.length() &amp;lt; 4) {&lt;br /&gt;
        for (int i=input.length()-1;i&amp;gt;=0;i--) {&lt;br /&gt;
            tokens.insert(tokens.begin(), input.at(i));&lt;br /&gt;
        }&lt;br /&gt;
    } else {&lt;br /&gt;
        for (int i=input.length()-1;i&amp;gt;=0;i--) {&lt;br /&gt;
            tokens.insert(tokens.begin(),input.at(i));&lt;br /&gt;
            if ((input.length() -i) % 3 == 0) {&lt;br /&gt;
                tokens.insert(tokens.begin(),&#039;,&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    // Parse, insert exponents, joiners&lt;br /&gt;
    vector&amp;lt;string&amp;gt; groups = split(tokens, &amp;quot;,&amp;quot;);&lt;br /&gt;
    vector&amp;lt;string&amp;gt; parserTokens;&lt;br /&gt;
    parserTokens.reserve(input.length()*2);&lt;br /&gt;
    for (size_t gi=0; gi != groups.size(); gi++) {&lt;br /&gt;
        switch (groups[gi].length()) {&lt;br /&gt;
        case 3:&lt;br /&gt;
        {&lt;br /&gt;
            vector&amp;lt;int&amp;gt; p = {&lt;br /&gt;
                stoi(groups[gi].substr(0,1)),&lt;br /&gt;
                stoi(groups[gi].substr(1))&lt;br /&gt;
            };&lt;br /&gt;
            if (p[0] != 0) {&lt;br /&gt;
                parserTokens.push_back(E0Literals[p[0]]);&lt;br /&gt;
                parserTokens.push_back(&amp;quot;H&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            if (p[1] != 0 &amp;amp;&amp;amp; p[1] &amp;lt; 10) {&lt;br /&gt;
                parserTokens.push_back(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                parserTokens.push_back(E0Literals[p[1]]);&lt;br /&gt;
            } else if (p[1] != 0 &amp;amp;&amp;amp; p[1] &amp;lt; 20) {&lt;br /&gt;
                parserTokens.push_back(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                parserTokens.push_back(TNLiterals[p[1]-11]);&lt;br /&gt;
            } else {&lt;br /&gt;
                if (groups[gi].at(1) != &#039;0&#039;) {&lt;br /&gt;
                    parserTokens.push_back(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                    parserTokens.push_back(&lt;br /&gt;
                        E1Literals[stoi(groups[gi].substr(1,1))-1]&lt;br /&gt;
                    );&lt;br /&gt;
                }&lt;br /&gt;
                if (groups[gi].at(2) != &#039;0&#039;) {&lt;br /&gt;
                    parserTokens.push_back(&lt;br /&gt;
                        E0Literals[stoi(groups[gi].substr(2,1))]&lt;br /&gt;
                    );&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        case 2:&lt;br /&gt;
        {&lt;br /&gt;
            int p = stoi(groups[gi]);&lt;br /&gt;
            if (p &amp;lt; 10) {&lt;br /&gt;
                parserTokens.push_back(E0Literals[p]);&lt;br /&gt;
            } else if (p &amp;lt; 20) {&lt;br /&gt;
                parserTokens.push_back(TNLiterals[p-11]);&lt;br /&gt;
            } else {&lt;br /&gt;
                parserTokens.push_back(&lt;br /&gt;
                    E1Literals[stoi(groups[gi].substr(0,1))-1]&lt;br /&gt;
                );&lt;br /&gt;
                if (groups[gi].at(1) != &#039;0&#039;) {&lt;br /&gt;
                    parserTokens.push_back(&lt;br /&gt;
                        E0Literals[stoi(groups[gi].substr(1,1))]&lt;br /&gt;
                    );&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        case 1:&lt;br /&gt;
        {&lt;br /&gt;
            int p = stoi(groups[gi]);&lt;br /&gt;
            parserTokens.push_back(E0Literals[p]);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        } /* switch */&lt;br /&gt;
        if (gi == groups.size() - 2 &amp;amp;&amp;amp; groups[gi] != &amp;quot;000&amp;quot;) {&lt;br /&gt;
            parserTokens.push_back(&amp;quot;T&amp;quot;);&lt;br /&gt;
        } else if (gi == groups.size() - 3) {&lt;br /&gt;
            parserTokens.push_back(&amp;quot;M&amp;quot;);&lt;br /&gt;
        } else if (gi == groups.size() - 4) {&lt;br /&gt;
            parserTokens.push_back(&amp;quot;B&amp;quot;);&lt;br /&gt;
        } else if (gi == groups.size() - 5) {&lt;br /&gt;
            parserTokens.push_back(&amp;quot;Tr&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        } /* for */&lt;br /&gt;
        for (int i=0; i &amp;lt; parserTokens.size() - 1; i++) {&lt;br /&gt;
            string s = parserTokens.at(i);&lt;br /&gt;
            if (s == &amp;quot;H&amp;quot;) {&lt;br /&gt;
                result.append(&amp;quot;hundred&amp;quot;);&lt;br /&gt;
            } else if (s == &amp;quot;T&amp;quot;) {&lt;br /&gt;
                result.append(&amp;quot;thousand&amp;quot;);&lt;br /&gt;
            } else if (s == &amp;quot;M&amp;quot;) {&lt;br /&gt;
                result.append(&amp;quot;million&amp;quot;);&lt;br /&gt;
            } else if (s == &amp;quot;B&amp;quot;) {&lt;br /&gt;
                result.append(&amp;quot;billion&amp;quot;);&lt;br /&gt;
            } else if (s == &amp;quot;Tr&amp;quot;) {&lt;br /&gt;
                result.append(&amp;quot;trillion&amp;quot;);&lt;br /&gt;
            } else if (s == &amp;quot;&amp;amp;&amp;quot;) {&lt;br /&gt;
                result.append(&amp;quot;and&amp;quot;);&lt;br /&gt;
            } else {&lt;br /&gt;
                result.append(s);&lt;br /&gt;
            }&lt;br /&gt;
            result.append(&amp;quot; &amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        auto s = parserTokens.back();&lt;br /&gt;
        if (s == &amp;quot;H&amp;quot;) {&lt;br /&gt;
            result.append(&amp;quot;hundred&amp;quot;);&lt;br /&gt;
        } else if (s == &amp;quot;T&amp;quot;) {&lt;br /&gt;
            result.append(&amp;quot;thousand&amp;quot;);&lt;br /&gt;
        } else if (s == &amp;quot;M&amp;quot;) {&lt;br /&gt;
            result.append(&amp;quot;million&amp;quot;);&lt;br /&gt;
        } else if (s == &amp;quot;B&amp;quot;) {&lt;br /&gt;
            result.append(&amp;quot;billion&amp;quot;);&lt;br /&gt;
        } else if (s == &amp;quot;Tr&amp;quot;) {&lt;br /&gt;
            result.append(&amp;quot;trillion&amp;quot;);&lt;br /&gt;
        } else if (s == &amp;quot;&amp;amp;&amp;quot;) {&lt;br /&gt;
            result.append(&amp;quot;and&amp;quot;);&lt;br /&gt;
        } else {&lt;br /&gt;
            result.append(s);&lt;br /&gt;
        }&lt;br /&gt;
    return result;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rust ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;rust&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
use std::iter::Iterator;&lt;br /&gt;
use std::ops::Deref;&lt;br /&gt;
use std::str::FromStr;&lt;br /&gt;
struct IntToWords;&lt;br /&gt;
impl IntToWords&lt;br /&gt;
{&lt;br /&gt;
    // Using Option, because I cannot figure out how to return generic errors&lt;br /&gt;
    pub fn parse_value(&amp;amp;self, input: &amp;amp;String) -&amp;gt; Option&amp;lt;String&amp;gt;&lt;br /&gt;
    {&lt;br /&gt;
        let E0Literals: Vec&amp;lt;&amp;amp;&#039;static str&amp;gt; = &amp;quot;zero,one,two,three,four,five,six,seven,eight,nine&amp;quot;.split(&#039;,&#039;).collect();&lt;br /&gt;
        let TNLiterals: Vec&amp;lt;&amp;amp;&#039;static str&amp;gt; = &amp;quot;eleven,twelve,thirteen,fourteen,fifteen,sixteen,seventeen,eighteen,nineteen&amp;quot;.split(&#039;,&#039;).collect();&lt;br /&gt;
        let E1Literals: Vec&amp;lt;&amp;amp;&#039;static str&amp;gt; = &amp;quot;ten,twenty,thirty,forty,fifty,sixty,seventy,eighty,ninety&amp;quot;.split(&#039;,&#039;).collect();&lt;br /&gt;
        let mut result: String = String::from(&amp;quot;&amp;quot;);&lt;br /&gt;
        let parsed_value = u64::from_str(input);&lt;br /&gt;
        if parsed_value.is_err() {&lt;br /&gt;
            return Some(String::from(&amp;quot;invalid&amp;quot;));&lt;br /&gt;
        }&lt;br /&gt;
        let num_commas = (input.len() as f32/6.0).ceil();&lt;br /&gt;
        // Split into digit groups&lt;br /&gt;
        let mut tokens: String = &amp;quot;&amp;quot;.to_string();&lt;br /&gt;
        tokens.reserve(input.len()+num_commas as usize);&lt;br /&gt;
        if input.len() &amp;lt; 4 {&lt;br /&gt;
            let mut i = input.len()-1;&lt;br /&gt;
            loop {&lt;br /&gt;
                tokens.insert(0, input.chars().nth(i).unwrap());&lt;br /&gt;
                if i &amp;gt; 0 { i -= 1; } else { break; }&lt;br /&gt;
            }&lt;br /&gt;
        } else {&lt;br /&gt;
            let mut i = input.len()-1;&lt;br /&gt;
            loop {&lt;br /&gt;
                tokens.insert(0,input.chars().nth(i).unwrap());&lt;br /&gt;
                if (input.len()-i) % 3 == 0 {&lt;br /&gt;
                    tokens.insert(0,&#039;,&#039;);&lt;br /&gt;
                }&lt;br /&gt;
                if i &amp;gt; 0 { i -= 1; } else { break; }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        // Parse the digit groups&lt;br /&gt;
        let groups : Vec&amp;lt;&amp;amp;str&amp;gt; = tokens.split(&#039;,&#039;).collect();&lt;br /&gt;
        let mut parser_tokens:Vec&amp;lt;&amp;amp;str&amp;gt; = Vec::new();&lt;br /&gt;
        for gi in 0..groups.len() {&lt;br /&gt;
            match groups[gi].len() {&lt;br /&gt;
                3 =&amp;gt; {&lt;br /&gt;
                    let p = [&lt;br /&gt;
                        usize::from_str(&amp;amp;groups[gi].chars().as_str()[0..1]).unwrap(),&lt;br /&gt;
                        usize::from_str(&amp;amp;groups[gi].chars().as_str()[1..]).unwrap()&lt;br /&gt;
                    ];&lt;br /&gt;
                    let p1 = (p[1] as f32/10_f32).floor() as u32;&lt;br /&gt;
                    let p2 = p[1] as u32 - (p1 as u32 * 10);&lt;br /&gt;
                    if p[0] != 0 {&lt;br /&gt;
                        parser_tokens.push(E0Literals[p[0]]);&lt;br /&gt;
                        parser_tokens.push(&amp;quot;H&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    if p[1] != 0 &amp;amp;&amp;amp; p[1] &amp;lt; 10 {&lt;br /&gt;
                        parser_tokens.push(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                        parser_tokens.push(E0Literals[p[1]]);&lt;br /&gt;
                    } else if p[1] != 0 &amp;amp;&amp;amp; p[1] &amp;lt; 20 {&lt;br /&gt;
                        parser_tokens.push(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                        parser_tokens.push(TNLiterals[p[1]-11]);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        if groups[gi].chars().nth(1).unwrap() != &#039;0&#039; {&lt;br /&gt;
                            parser_tokens.push(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                            parser_tokens.push(&lt;br /&gt;
                                E1Literals[p1 as usize - 1]&lt;br /&gt;
                            );&lt;br /&gt;
                        }&lt;br /&gt;
                        if groups[gi].chars().nth(2).unwrap() != &#039;0&#039; {&lt;br /&gt;
                            parser_tokens.push(&lt;br /&gt;
                                E0Literals[p2 as usize]&lt;br /&gt;
                            );&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                2 =&amp;gt; {&lt;br /&gt;
                    let p = usize::from_str(&amp;amp;groups[gi]).unwrap();&lt;br /&gt;
                    let p1 = (p as f32/10_f32).floor() as u32;&lt;br /&gt;
                    let p2 = p as u32 - (p1 * 10);&lt;br /&gt;
                    if p &amp;lt; 10 {&lt;br /&gt;
                        parser_tokens.push(E0Literals[p]);&lt;br /&gt;
                    } else if p &amp;lt; 20 {&lt;br /&gt;
                        parser_tokens.push(TNLiterals[p-11]);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        parser_tokens.push(&lt;br /&gt;
                            E1Literals[p1 as usize-1]&lt;br /&gt;
                        );&lt;br /&gt;
                        if groups[gi].chars().nth(1).unwrap() != &#039;0&#039; {&lt;br /&gt;
                            parser_tokens.push(&lt;br /&gt;
                                E0Literals[p2 as usize]&lt;br /&gt;
                            );&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                1 =&amp;gt; {&lt;br /&gt;
                    let p = usize::from_str(groups[gi]).unwrap();&lt;br /&gt;
                    parser_tokens.push(E0Literals[p]);&lt;br /&gt;
                }&lt;br /&gt;
                _ =&amp;gt; {}&lt;br /&gt;
            } /* match */&lt;br /&gt;
            if groups.len() &amp;gt;= 2 &amp;amp;&amp;amp; gi == groups.len() - 2 &amp;amp;&amp;amp; groups[gi] != &amp;quot;000&amp;quot; {&lt;br /&gt;
                parser_tokens.push(&amp;quot;T&amp;quot;);&lt;br /&gt;
            } else if groups.len() &amp;gt;= 3 &amp;amp;&amp;amp; gi == groups.len() - 3 {&lt;br /&gt;
                parser_tokens.push(&amp;quot;M&amp;quot;);&lt;br /&gt;
            } else if groups.len() &amp;gt;= 4 &amp;amp;&amp;amp; gi == groups.len() - 4 {&lt;br /&gt;
                parser_tokens.push(&amp;quot;B&amp;quot;);&lt;br /&gt;
            } else if groups.len() &amp;gt;= 5 &amp;amp;&amp;amp; gi == groups.len() - 5 {&lt;br /&gt;
                parser_tokens.push(&amp;quot;Tr&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        // Convert tokens to words&lt;br /&gt;
        for i in 0..parser_tokens.len() - 1 {&lt;br /&gt;
            let s = parser_tokens[i];&lt;br /&gt;
            result.push_str(match s {&lt;br /&gt;
                &amp;quot;H&amp;quot; =&amp;gt; &amp;quot;hundred&amp;quot;,&lt;br /&gt;
                &amp;quot;T&amp;quot; =&amp;gt; &amp;quot;thousand&amp;quot;,&lt;br /&gt;
                &amp;quot;M&amp;quot; =&amp;gt; &amp;quot;million&amp;quot;,&lt;br /&gt;
                &amp;quot;B&amp;quot; =&amp;gt; &amp;quot;billion&amp;quot;,&lt;br /&gt;
                &amp;quot;Tr&amp;quot; =&amp;gt; &amp;quot;trillion&amp;quot;,&lt;br /&gt;
                &amp;quot;&amp;amp;&amp;quot; =&amp;gt; &amp;quot;and&amp;quot;,&lt;br /&gt;
                _ =&amp;gt; s&lt;br /&gt;
            });&lt;br /&gt;
            result.push_str(&amp;quot; &amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        let s = parser_tokens.last().unwrap().deref();&lt;br /&gt;
        result.push_str(match s {&lt;br /&gt;
            &amp;quot;H&amp;quot; =&amp;gt; &amp;quot;hundred&amp;quot;,&lt;br /&gt;
            &amp;quot;T&amp;quot; =&amp;gt; &amp;quot;thousand&amp;quot;,&lt;br /&gt;
            &amp;quot;M&amp;quot; =&amp;gt; &amp;quot;million&amp;quot;,&lt;br /&gt;
            &amp;quot;B&amp;quot; =&amp;gt; &amp;quot;billion&amp;quot;,&lt;br /&gt;
            &amp;quot;Tr&amp;quot; =&amp;gt; &amp;quot;trillion&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;amp;&amp;quot; =&amp;gt; &amp;quot;and&amp;quot;,&lt;br /&gt;
            _ =&amp;gt; s&lt;br /&gt;
        });&lt;br /&gt;
        Some(result)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=Common_Algorithms&amp;diff=75</id>
		<title>Common Algorithms</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=Common_Algorithms&amp;diff=75"/>
		<updated>2025-04-09T09:58:12Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Information Technology]]&lt;br /&gt;
The code published on this page is provided with the conditions of the MIT license.&lt;br /&gt;
&lt;br /&gt;
== Integer to Words ==&lt;br /&gt;
This converts an integer into English words. Solving this problem was an interesting exercise, as I ended up parsing in 3 stages which were: splitting the digit groups, inserting symbols for base 10 exponents and ampersands after groups of hundreds, and then converting the symbols into words.&lt;br /&gt;
&lt;br /&gt;
I initially started my implementation in Java, then after finishing, moved onto C++. The Rust version was the most difficult, as, of time of writing it, I was still fairly new to the language.&lt;br /&gt;
&lt;br /&gt;
=== Java ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
package com.bgcottrell;&lt;br /&gt;
&lt;br /&gt;
import java.util.*;&lt;br /&gt;
&lt;br /&gt;
public class Main {&lt;br /&gt;
    public static String[] E0Literals = &amp;quot;zero,one,two,three,four,five,six,seven,eight,nine&amp;quot;.split(&amp;quot;,&amp;quot;);&lt;br /&gt;
    public static String[] TNLiterals = &amp;quot;eleven,twelve,thirteen,fourteen,fifteen,sixteen,seventeen,eighteen,nineteen&amp;quot;.split(&amp;quot;,&amp;quot;);&lt;br /&gt;
    public static String[] E1Literals = &amp;quot;ten,twenty,thirty,forty,fifty,sixty,seventy,eighty,ninety&amp;quot;.split(&amp;quot;,&amp;quot;);&lt;br /&gt;
    public static String parseIntString(String strValue)&lt;br /&gt;
    {&lt;br /&gt;
        StringBuilder result = new StringBuilder();&lt;br /&gt;
        Long parsedValue = 0L;&lt;br /&gt;
        //int r = 0;&lt;br /&gt;
        try {&lt;br /&gt;
            parsedValue = Long.parseUnsignedLong(strValue);&lt;br /&gt;
            //r = strValue.length();&lt;br /&gt;
        } catch (NumberFormatException e) {&lt;br /&gt;
            throw new RuntimeException(e);&lt;br /&gt;
        }&lt;br /&gt;
        // Split with commas&lt;br /&gt;
        int numCommas = (int)Math.ceil((double) strValue.length() /6);&lt;br /&gt;
        StringBuilder tokens = new StringBuilder(strValue.length() + numCommas);&lt;br /&gt;
        if (strValue.length() &amp;lt; 4) {&lt;br /&gt;
            for (int i = strValue.length() - 1; i &amp;gt;= 0; i--) {&lt;br /&gt;
                tokens.insert(0, strValue.charAt(i));&lt;br /&gt;
            }&lt;br /&gt;
        } else {&lt;br /&gt;
            for (int i = strValue.length() - 1; i &amp;gt;= 0; i--) {&lt;br /&gt;
                tokens.insert(0, strValue.charAt(i));&lt;br /&gt;
                if ((strValue.length() - i) % 3 == 0 &amp;amp;&amp;amp; (i &amp;gt; 0)) {&lt;br /&gt;
                    tokens.insert(0, &#039;,&#039;);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        System.out.printf(&amp;quot;(%s) &amp;quot;,tokens);&lt;br /&gt;
&lt;br /&gt;
        // Parse, insert exponents, hundred&#039;s joiners&lt;br /&gt;
        String groups[] = tokens.toString().split(&amp;quot;,&amp;quot;);&lt;br /&gt;
        ArrayList&amp;lt;String&amp;gt; parserTokens = new ArrayList&amp;lt;&amp;gt;();&lt;br /&gt;
        for (int gi=0; gi &amp;lt; groups.length; gi++) {&lt;br /&gt;
            switch (groups[gi].length()) {&lt;br /&gt;
                case 3: {&lt;br /&gt;
                    Integer p[] = {&lt;br /&gt;
                            Integer.parseUnsignedInt(String.valueOf(groups[gi].charAt(0))),&lt;br /&gt;
                            Integer.parseUnsignedInt(groups[gi].substring(1)),&lt;br /&gt;
                    };&lt;br /&gt;
                    if (p[0] != 0) {&lt;br /&gt;
                        parserTokens.add(E0Literals[p[0]]);&lt;br /&gt;
                        parserTokens.add(&amp;quot;H&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    if (p[1] != 0 &amp;amp;&amp;amp; p[1] &amp;lt; 10) {&lt;br /&gt;
                        parserTokens.add(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                        parserTokens.add(E0Literals[p[1]]);&lt;br /&gt;
                    } else if (p[1] != 0 &amp;amp;&amp;amp; p[1] &amp;lt; 20) {&lt;br /&gt;
                        parserTokens.add(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                        parserTokens.add(TNLiterals[p[1] - 11]);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        if (groups[gi].charAt(1) != &#039;0&#039;) {&lt;br /&gt;
                            parserTokens.add(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                            parserTokens.add(&lt;br /&gt;
                                    E1Literals[Integer.parseUnsignedInt(String.valueOf(groups[gi].charAt(1))) - 1]&lt;br /&gt;
                            );&lt;br /&gt;
                        }&lt;br /&gt;
                        if (groups[gi].charAt(2) != &#039;0&#039;) {&lt;br /&gt;
                            parserTokens.add(&lt;br /&gt;
                                E0Literals[Integer.parseUnsignedInt(String.valueOf(groups[gi].charAt(2)))]&lt;br /&gt;
                            );&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
                case 2:&lt;br /&gt;
                {&lt;br /&gt;
                    Integer p = Integer.parseUnsignedInt(groups[gi]);&lt;br /&gt;
                    if (p &amp;lt; 10) {&lt;br /&gt;
                        parserTokens.add(E0Literals[p]);&lt;br /&gt;
                    } else if (p &amp;lt; 20) {&lt;br /&gt;
                        parserTokens.add(TNLiterals[p - 11]);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        parserTokens.add(&lt;br /&gt;
                                E1Literals[Integer.parseUnsignedInt(String.valueOf(groups[gi].charAt(0))) - 1]&lt;br /&gt;
                        );&lt;br /&gt;
                        if (groups[gi].charAt(1) != &#039;0&#039;) {&lt;br /&gt;
                            parserTokens.add(&lt;br /&gt;
                                    E0Literals[Integer.parseUnsignedInt(String.valueOf(groups[gi].charAt(1)))]&lt;br /&gt;
                            );&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
                case 1: {&lt;br /&gt;
                    Integer p = Integer.parseUnsignedInt(groups[gi]);&lt;br /&gt;
                    parserTokens.add(E0Literals[p]);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            if (gi == groups.length - 2 &amp;amp;&amp;amp; groups[gi] != &amp;quot;000&amp;quot;) {&lt;br /&gt;
                parserTokens.add(&amp;quot;T&amp;quot;);&lt;br /&gt;
            } else if (gi == groups.length - 3) {&lt;br /&gt;
                parserTokens.add(&amp;quot;M&amp;quot;);&lt;br /&gt;
            } else if (gi == groups.length - 4) {&lt;br /&gt;
                parserTokens.add(&amp;quot;B&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        //System.out.printf(&amp;quot;Parsed: %s&amp;quot;, parserTokens);&lt;br /&gt;
        for (int i =0; i &amp;lt; parserTokens.size() - 1;i++) {&lt;br /&gt;
            switch (parserTokens.get(i)) {&lt;br /&gt;
                case &amp;quot;H&amp;quot;:&lt;br /&gt;
                    result.append(&amp;quot;hundred&amp;quot;);&lt;br /&gt;
                    break;&lt;br /&gt;
                case &amp;quot;T&amp;quot;:&lt;br /&gt;
                    result.append(&amp;quot;thousand&amp;quot;);&lt;br /&gt;
                    break;&lt;br /&gt;
                case &amp;quot;M&amp;quot;:&lt;br /&gt;
                    result.append(&amp;quot;million&amp;quot;);&lt;br /&gt;
                    break;&lt;br /&gt;
                case &amp;quot;B&amp;quot;:&lt;br /&gt;
                    result.append(&amp;quot;billion&amp;quot;);&lt;br /&gt;
                    break;&lt;br /&gt;
                case &amp;quot;&amp;amp;&amp;quot;:&lt;br /&gt;
                    result.append(&amp;quot;and&amp;quot;);&lt;br /&gt;
                    break;&lt;br /&gt;
                default:&lt;br /&gt;
                    result.append(parserTokens.get(i));&lt;br /&gt;
            }&lt;br /&gt;
            result.append(&amp;quot; &amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        switch (parserTokens.getLast()) {&lt;br /&gt;
            case &amp;quot;H&amp;quot;:&lt;br /&gt;
                result.append(&amp;quot;hundred&amp;quot;);&lt;br /&gt;
                break;&lt;br /&gt;
            case &amp;quot;T&amp;quot;:&lt;br /&gt;
                result.append(&amp;quot;thousand&amp;quot;);&lt;br /&gt;
                break;&lt;br /&gt;
            case &amp;quot;M&amp;quot;:&lt;br /&gt;
                result.append(&amp;quot;million&amp;quot;);&lt;br /&gt;
                break;&lt;br /&gt;
            case &amp;quot;B&amp;quot;:&lt;br /&gt;
                result.append(&amp;quot;billion&amp;quot;);&lt;br /&gt;
            case &amp;quot;&amp;amp;&amp;quot;:&lt;br /&gt;
                result.append(&amp;quot;and&amp;quot;);&lt;br /&gt;
            default:&lt;br /&gt;
                result.append(parserTokens.getLast());&lt;br /&gt;
        }&lt;br /&gt;
        return result.toString();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== C++17 ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;cmath&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;iomanip&amp;gt;&lt;br /&gt;
#include &amp;lt;vector&amp;gt;&lt;br /&gt;
#include &amp;lt;ranges&amp;gt;&lt;br /&gt;
#include &amp;lt;string_view&amp;gt;&lt;br /&gt;
#include &amp;lt;algorithm&amp;gt;&lt;br /&gt;
#include &amp;lt;format&amp;gt;&lt;br /&gt;
static string IntToWords(const string&amp;amp; input)&lt;br /&gt;
{&lt;br /&gt;
    static array E0Literals = {&amp;quot;zero&amp;quot;, &amp;quot;one&amp;quot;, &amp;quot;two&amp;quot;, &amp;quot;three&amp;quot;, &amp;quot;four&amp;quot;, &amp;quot;five&amp;quot;, &amp;quot;six&amp;quot;, &amp;quot;seven&amp;quot;, &amp;quot;eight&amp;quot;, &amp;quot;nine&amp;quot;};&lt;br /&gt;
    static array TNLiterals = {&amp;quot;eleven&amp;quot;, &amp;quot;twelve&amp;quot;, &amp;quot;thirteen&amp;quot;, &amp;quot;fourteen&amp;quot;, &amp;quot;fifteen&amp;quot;, &amp;quot;sixteen&amp;quot;, &amp;quot;seventeen&amp;quot;, &amp;quot;eighteen&amp;quot;, &amp;quot;nineteen&amp;quot;};&lt;br /&gt;
    static array E1Literals = {&amp;quot;ten&amp;quot;, &amp;quot;twenty&amp;quot;, &amp;quot;thirty&amp;quot;, &amp;quot;forty&amp;quot;, &amp;quot;fifty&amp;quot;, &amp;quot;sixty&amp;quot;, &amp;quot;seventy&amp;quot;, &amp;quot;eighty&amp;quot;, &amp;quot;ninety&amp;quot;};&lt;br /&gt;
    string result;&lt;br /&gt;
    try {&lt;br /&gt;
        ulong parsedValue = stoul(input);&lt;br /&gt;
    } catch (const exception&amp;amp; ex) {&lt;br /&gt;
        return &amp;quot;invalid&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    // Split with commas, make it easier to parse&lt;br /&gt;
    const auto numCommas = int(ceil(input.length()/6));&lt;br /&gt;
    string tokens;&lt;br /&gt;
    tokens.reserve(input.length()+numCommas);&lt;br /&gt;
    if (input.length() &amp;lt; 4) {&lt;br /&gt;
        for (int i=input.length()-1;i&amp;gt;=0;i--) {&lt;br /&gt;
            tokens.insert(tokens.begin(), input.at(i));&lt;br /&gt;
        }&lt;br /&gt;
    } else {&lt;br /&gt;
        for (int i=input.length()-1;i&amp;gt;=0;i--) {&lt;br /&gt;
            tokens.insert(tokens.begin(),input.at(i));&lt;br /&gt;
            if ((input.length() -i) % 3 == 0) {&lt;br /&gt;
                tokens.insert(tokens.begin(),&#039;,&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    // Parse, insert exponents, joiners&lt;br /&gt;
    vector&amp;lt;string&amp;gt; groups = split(tokens, &amp;quot;,&amp;quot;);&lt;br /&gt;
    vector&amp;lt;string&amp;gt; parserTokens;&lt;br /&gt;
    parserTokens.reserve(input.length()*2);&lt;br /&gt;
    for (size_t gi=0; gi != groups.size(); gi++) {&lt;br /&gt;
        switch (groups[gi].length()) {&lt;br /&gt;
        case 3:&lt;br /&gt;
        {&lt;br /&gt;
            vector&amp;lt;int&amp;gt; p = {&lt;br /&gt;
                stoi(groups[gi].substr(0,1)),&lt;br /&gt;
                stoi(groups[gi].substr(1))&lt;br /&gt;
            };&lt;br /&gt;
            if (p[0] != 0) {&lt;br /&gt;
                parserTokens.push_back(E0Literals[p[0]]);&lt;br /&gt;
                parserTokens.push_back(&amp;quot;H&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            if (p[1] != 0 &amp;amp;&amp;amp; p[1] &amp;lt; 10) {&lt;br /&gt;
                parserTokens.push_back(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                parserTokens.push_back(E0Literals[p[1]]);&lt;br /&gt;
            } else if (p[1] != 0 &amp;amp;&amp;amp; p[1] &amp;lt; 20) {&lt;br /&gt;
                parserTokens.push_back(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                parserTokens.push_back(TNLiterals[p[1]-11]);&lt;br /&gt;
            } else {&lt;br /&gt;
                if (groups[gi].at(1) != &#039;0&#039;) {&lt;br /&gt;
                    parserTokens.push_back(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                    parserTokens.push_back(&lt;br /&gt;
                        E1Literals[stoi(groups[gi].substr(1,1))-1]&lt;br /&gt;
                    );&lt;br /&gt;
                }&lt;br /&gt;
                if (groups[gi].at(2) != &#039;0&#039;) {&lt;br /&gt;
                    parserTokens.push_back(&lt;br /&gt;
                        E0Literals[stoi(groups[gi].substr(2,1))]&lt;br /&gt;
                    );&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        case 2:&lt;br /&gt;
        {&lt;br /&gt;
            int p = stoi(groups[gi]);&lt;br /&gt;
            if (p &amp;lt; 10) {&lt;br /&gt;
                parserTokens.push_back(E0Literals[p]);&lt;br /&gt;
            } else if (p &amp;lt; 20) {&lt;br /&gt;
                parserTokens.push_back(TNLiterals[p-11]);&lt;br /&gt;
            } else {&lt;br /&gt;
                parserTokens.push_back(&lt;br /&gt;
                    E1Literals[stoi(groups[gi].substr(0,1))-1]&lt;br /&gt;
                );&lt;br /&gt;
                if (groups[gi].at(1) != &#039;0&#039;) {&lt;br /&gt;
                    parserTokens.push_back(&lt;br /&gt;
                        E0Literals[stoi(groups[gi].substr(1,1))]&lt;br /&gt;
                    );&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        case 1:&lt;br /&gt;
        {&lt;br /&gt;
            int p = stoi(groups[gi]);&lt;br /&gt;
            parserTokens.push_back(E0Literals[p]);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        } /* switch */&lt;br /&gt;
        if (gi == groups.size() - 2 &amp;amp;&amp;amp; groups[gi] != &amp;quot;000&amp;quot;) {&lt;br /&gt;
            parserTokens.push_back(&amp;quot;T&amp;quot;);&lt;br /&gt;
        } else if (gi == groups.size() - 3) {&lt;br /&gt;
            parserTokens.push_back(&amp;quot;M&amp;quot;);&lt;br /&gt;
        } else if (gi == groups.size() - 4) {&lt;br /&gt;
            parserTokens.push_back(&amp;quot;B&amp;quot;);&lt;br /&gt;
        } else if (gi == groups.size() - 5) {&lt;br /&gt;
            parserTokens.push_back(&amp;quot;Tr&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        } /* for */&lt;br /&gt;
        for (int i=0; i &amp;lt; parserTokens.size() - 1; i++) {&lt;br /&gt;
            string s = parserTokens.at(i);&lt;br /&gt;
            if (s == &amp;quot;H&amp;quot;) {&lt;br /&gt;
                result.append(&amp;quot;hundred&amp;quot;);&lt;br /&gt;
            } else if (s == &amp;quot;T&amp;quot;) {&lt;br /&gt;
                result.append(&amp;quot;thousand&amp;quot;);&lt;br /&gt;
            } else if (s == &amp;quot;M&amp;quot;) {&lt;br /&gt;
                result.append(&amp;quot;million&amp;quot;);&lt;br /&gt;
            } else if (s == &amp;quot;B&amp;quot;) {&lt;br /&gt;
                result.append(&amp;quot;billion&amp;quot;);&lt;br /&gt;
            } else if (s == &amp;quot;Tr&amp;quot;) {&lt;br /&gt;
                result.append(&amp;quot;trillion&amp;quot;);&lt;br /&gt;
            } else if (s == &amp;quot;&amp;amp;&amp;quot;) {&lt;br /&gt;
                result.append(&amp;quot;and&amp;quot;);&lt;br /&gt;
            } else {&lt;br /&gt;
                result.append(s);&lt;br /&gt;
            }&lt;br /&gt;
            result.append(&amp;quot; &amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        auto s = parserTokens.back();&lt;br /&gt;
        if (s == &amp;quot;H&amp;quot;) {&lt;br /&gt;
            result.append(&amp;quot;hundred&amp;quot;);&lt;br /&gt;
        } else if (s == &amp;quot;T&amp;quot;) {&lt;br /&gt;
            result.append(&amp;quot;thousand&amp;quot;);&lt;br /&gt;
        } else if (s == &amp;quot;M&amp;quot;) {&lt;br /&gt;
            result.append(&amp;quot;million&amp;quot;);&lt;br /&gt;
        } else if (s == &amp;quot;B&amp;quot;) {&lt;br /&gt;
            result.append(&amp;quot;billion&amp;quot;);&lt;br /&gt;
        } else if (s == &amp;quot;Tr&amp;quot;) {&lt;br /&gt;
            result.append(&amp;quot;trillion&amp;quot;);&lt;br /&gt;
        } else if (s == &amp;quot;&amp;amp;&amp;quot;) {&lt;br /&gt;
            result.append(&amp;quot;and&amp;quot;);&lt;br /&gt;
        } else {&lt;br /&gt;
            result.append(s);&lt;br /&gt;
        }&lt;br /&gt;
    return result;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rust ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;rust&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
use std::iter::Iterator;&lt;br /&gt;
use std::ops::Deref;&lt;br /&gt;
use std::str::FromStr;&lt;br /&gt;
struct IntToWords;&lt;br /&gt;
impl IntToWords&lt;br /&gt;
{&lt;br /&gt;
    // Using Option, because I cannot figure out how to return generic errors&lt;br /&gt;
    pub fn parse_value(&amp;amp;self, input: &amp;amp;String) -&amp;gt; Option&amp;lt;String&amp;gt;&lt;br /&gt;
    {&lt;br /&gt;
        let E0Literals: Vec&amp;lt;&amp;amp;&#039;static str&amp;gt; = &amp;quot;zero,one,two,three,four,five,six,seven,eight,nine&amp;quot;.split(&#039;,&#039;).collect();&lt;br /&gt;
        let TNLiterals: Vec&amp;lt;&amp;amp;&#039;static str&amp;gt; = &amp;quot;eleven,twelve,thirteen,fourteen,fifteen,sixteen,seventeen,eighteen,nineteen&amp;quot;.split(&#039;,&#039;).collect();&lt;br /&gt;
        let E1Literals: Vec&amp;lt;&amp;amp;&#039;static str&amp;gt; = &amp;quot;ten,twenty,thirty,forty,fifty,sixty,seventy,eighty,ninety&amp;quot;.split(&#039;,&#039;).collect();&lt;br /&gt;
        let mut result: String = String::from(&amp;quot;&amp;quot;);&lt;br /&gt;
        let parsed_value = u64::from_str(input);&lt;br /&gt;
        if parsed_value.is_err() {&lt;br /&gt;
            return Some(String::from(&amp;quot;invalid&amp;quot;));&lt;br /&gt;
        }&lt;br /&gt;
        let num_commas = (input.len() as f32/6.0).ceil();&lt;br /&gt;
        // Split into digit groups&lt;br /&gt;
        let mut tokens: String = &amp;quot;&amp;quot;.to_string();&lt;br /&gt;
        tokens.reserve(input.len()+num_commas as usize);&lt;br /&gt;
        if input.len() &amp;lt; 4 {&lt;br /&gt;
            let mut i = input.len()-1;&lt;br /&gt;
            loop {&lt;br /&gt;
                tokens.insert(0, input.chars().nth(i).unwrap());&lt;br /&gt;
                if i &amp;gt; 0 { i -= 1; } else { break; }&lt;br /&gt;
            }&lt;br /&gt;
        } else {&lt;br /&gt;
            let mut i = input.len()-1;&lt;br /&gt;
            loop {&lt;br /&gt;
                tokens.insert(0,input.chars().nth(i).unwrap());&lt;br /&gt;
                if (input.len()-i) % 3 == 0 {&lt;br /&gt;
                    tokens.insert(0,&#039;,&#039;);&lt;br /&gt;
                }&lt;br /&gt;
                if i &amp;gt; 0 { i -= 1; } else { break; }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        // Parse the digit groups&lt;br /&gt;
        let groups : Vec&amp;lt;&amp;amp;str&amp;gt; = tokens.split(&#039;,&#039;).collect();&lt;br /&gt;
        let mut parser_tokens:Vec&amp;lt;&amp;amp;str&amp;gt; = Vec::new();&lt;br /&gt;
        for gi in 0..groups.len() {&lt;br /&gt;
            match groups[gi].len() {&lt;br /&gt;
                3 =&amp;gt; {&lt;br /&gt;
                    let p = [&lt;br /&gt;
                        usize::from_str(&amp;amp;groups[gi].chars().as_str()[0..1]).unwrap(),&lt;br /&gt;
                        usize::from_str(&amp;amp;groups[gi].chars().as_str()[1..]).unwrap()&lt;br /&gt;
                    ];&lt;br /&gt;
                    let p1 = (p[1] as f32/10_f32).floor() as u32;&lt;br /&gt;
                    let p2 = p[1] as u32 - (p1 as u32 * 10);&lt;br /&gt;
                    if p[0] != 0 {&lt;br /&gt;
                        parser_tokens.push(E0Literals[p[0]]);&lt;br /&gt;
                        parser_tokens.push(&amp;quot;H&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    if p[1] != 0 &amp;amp;&amp;amp; p[1] &amp;lt; 10 {&lt;br /&gt;
                        parser_tokens.push(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                        parser_tokens.push(E0Literals[p[1]]);&lt;br /&gt;
                    } else if p[1] != 0 &amp;amp;&amp;amp; p[1] &amp;lt; 20 {&lt;br /&gt;
                        parser_tokens.push(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                        parser_tokens.push(TNLiterals[p[1]-11]);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        if groups[gi].chars().nth(1).unwrap() != &#039;0&#039; {&lt;br /&gt;
                            parser_tokens.push(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
                            parser_tokens.push(&lt;br /&gt;
                                E1Literals[p1 as usize - 1]&lt;br /&gt;
                            );&lt;br /&gt;
                        }&lt;br /&gt;
                        if groups[gi].chars().nth(2).unwrap() != &#039;0&#039; {&lt;br /&gt;
                            parser_tokens.push(&lt;br /&gt;
                                E0Literals[p2 as usize]&lt;br /&gt;
                            );&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                2 =&amp;gt; {&lt;br /&gt;
                    let p = usize::from_str(&amp;amp;groups[gi]).unwrap();&lt;br /&gt;
                    let p1 = (p as f32/10_f32).floor() as u32;&lt;br /&gt;
                    let p2 = p as u32 - (p1 * 10);&lt;br /&gt;
                    if p &amp;lt; 10 {&lt;br /&gt;
                        parser_tokens.push(E0Literals[p]);&lt;br /&gt;
                    } else if p &amp;lt; 20 {&lt;br /&gt;
                        parser_tokens.push(TNLiterals[p-11]);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        parser_tokens.push(&lt;br /&gt;
                            E1Literals[p1 as usize-1]&lt;br /&gt;
                        );&lt;br /&gt;
                        if groups[gi].chars().nth(1).unwrap() != &#039;0&#039; {&lt;br /&gt;
                            parser_tokens.push(&lt;br /&gt;
                                E0Literals[p2 as usize]&lt;br /&gt;
                            );&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                1 =&amp;gt; {&lt;br /&gt;
                    let p = usize::from_str(groups[gi]).unwrap();&lt;br /&gt;
                    parser_tokens.push(E0Literals[p]);&lt;br /&gt;
                }&lt;br /&gt;
                _ =&amp;gt; {}&lt;br /&gt;
            } /* match */&lt;br /&gt;
            if groups.len() &amp;gt;= 2 &amp;amp;&amp;amp; gi == groups.len() - 2 &amp;amp;&amp;amp; groups[gi] != &amp;quot;000&amp;quot; {&lt;br /&gt;
                parser_tokens.push(&amp;quot;T&amp;quot;);&lt;br /&gt;
            } else if groups.len() &amp;gt;= 3 &amp;amp;&amp;amp; gi == groups.len() - 3 {&lt;br /&gt;
                parser_tokens.push(&amp;quot;M&amp;quot;);&lt;br /&gt;
            } else if groups.len() &amp;gt;= 4 &amp;amp;&amp;amp; gi == groups.len() - 4 {&lt;br /&gt;
                parser_tokens.push(&amp;quot;B&amp;quot;);&lt;br /&gt;
            } else if groups.len() &amp;gt;= 5 &amp;amp;&amp;amp; gi == groups.len() - 5 {&lt;br /&gt;
                parser_tokens.push(&amp;quot;Tr&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        // Convert tokens to words&lt;br /&gt;
        for i in 0..parser_tokens.len() - 1 {&lt;br /&gt;
            let s = parser_tokens[i];&lt;br /&gt;
            result.push_str(match s {&lt;br /&gt;
                &amp;quot;H&amp;quot; =&amp;gt; &amp;quot;hundred&amp;quot;,&lt;br /&gt;
                &amp;quot;T&amp;quot; =&amp;gt; &amp;quot;thousand&amp;quot;,&lt;br /&gt;
                &amp;quot;M&amp;quot; =&amp;gt; &amp;quot;million&amp;quot;,&lt;br /&gt;
                &amp;quot;B&amp;quot; =&amp;gt; &amp;quot;billion&amp;quot;,&lt;br /&gt;
                &amp;quot;Tr&amp;quot; =&amp;gt; &amp;quot;trillion&amp;quot;,&lt;br /&gt;
                &amp;quot;&amp;amp;&amp;quot; =&amp;gt; &amp;quot;and&amp;quot;,&lt;br /&gt;
                _ =&amp;gt; s&lt;br /&gt;
            });&lt;br /&gt;
            result.push_str(&amp;quot; &amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        let s = parser_tokens.last().unwrap().deref();&lt;br /&gt;
        result.push_str(match s {&lt;br /&gt;
            &amp;quot;H&amp;quot; =&amp;gt; &amp;quot;hundred&amp;quot;,&lt;br /&gt;
            &amp;quot;T&amp;quot; =&amp;gt; &amp;quot;thousand&amp;quot;,&lt;br /&gt;
            &amp;quot;M&amp;quot; =&amp;gt; &amp;quot;million&amp;quot;,&lt;br /&gt;
            &amp;quot;B&amp;quot; =&amp;gt; &amp;quot;billion&amp;quot;,&lt;br /&gt;
            &amp;quot;Tr&amp;quot; =&amp;gt; &amp;quot;trillion&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;amp;&amp;quot; =&amp;gt; &amp;quot;and&amp;quot;,&lt;br /&gt;
            _ =&amp;gt; s&lt;br /&gt;
        });&lt;br /&gt;
        Some(result)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=Common_Algorithms&amp;diff=74</id>
		<title>Common Algorithms</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=Common_Algorithms&amp;diff=74"/>
		<updated>2025-04-09T09:19:21Z</updated>

		<summary type="html">&lt;p&gt;Root: Created page with &amp;quot;Category: Information Technology&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Information Technology]]&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=Category:Software_Development&amp;diff=73</id>
		<title>Category:Software Development</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=Category:Software_Development&amp;diff=73"/>
		<updated>2025-04-09T07:38:42Z</updated>

		<summary type="html">&lt;p&gt;Root: Created blank page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=Main_Page&amp;diff=72</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=Main_Page&amp;diff=72"/>
		<updated>2025-04-09T07:38:07Z</updated>

		<summary type="html">&lt;p&gt;Root: /* Directory */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://www.bgcottrell.com &amp;lt; Go back to bgcottrell.com]&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;Strong&amp;gt;Welcome&amp;lt;/Strong&amp;gt; ==&lt;br /&gt;
This is a place to store gathered ideas, providing a knowledge base, and more, sharing pieces of information that I&#039;ve found useful.&lt;br /&gt;
&lt;br /&gt;
=== Directory ===&lt;br /&gt;
&amp;lt;categorytree mode=&amp;quot;all&amp;quot; depth=&amp;quot;6&amp;quot;&amp;gt;Information Technology&amp;lt;/categorytree&amp;gt;&lt;br /&gt;
&amp;lt;categorytree mode=&amp;quot;all&amp;quot; depth=&amp;quot;6&amp;quot;&amp;gt;Food&amp;lt;/categorytree&amp;gt;&lt;br /&gt;
&amp;lt;categorytree mode=&amp;quot;all&amp;quot; depth=&amp;quot;6&amp;quot;&amp;gt;Software Development&amp;lt;/categorytree&amp;gt;&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=Qt_Framework&amp;diff=71</id>
		<title>Qt Framework</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=Qt_Framework&amp;diff=71"/>
		<updated>2025-04-09T07:37:51Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Software Development]]&lt;br /&gt;
== Tool Workarounds ==&lt;br /&gt;
&lt;br /&gt;
=== Creator ===&lt;br /&gt;
The Creator IDE still does not implement a style plugin, which, makes improving the contrast of widgets to be more difficult. The scrollbars still could have greater contrast. I&#039;ve used this stylesheet file, shown below, and passed it to the &amp;quot;-stylesheet&amp;quot; option to creator when launching it:&lt;br /&gt;
&lt;br /&gt;
 /* Define a style for the vertical scrollbar */&lt;br /&gt;
 QScrollBar:vertical {&lt;br /&gt;
     background: #3f3f3f; /* Set the background color */&lt;br /&gt;
 }&lt;br /&gt;
 /* Define a style for the horizontal scrollbar */&lt;br /&gt;
 QScrollBar:horizontal {&lt;br /&gt;
     background: #3f3f3f; /* Set the background color */&lt;br /&gt;
     &lt;br /&gt;
 }&lt;br /&gt;
 /* Define a style for the handle (the draggable part) of the scrollbar */&lt;br /&gt;
 QScrollBar::handle:vertical,&lt;br /&gt;
 QScrollBar::handle:horizontal {&lt;br /&gt;
     background: #999999; /* Set the color of the handle */&lt;br /&gt;
     min-height: 20px; /* Set the minimum height of the handle */&lt;br /&gt;
 }&lt;br /&gt;
 QLabel::Link, QLabel::LinkVisited {&lt;br /&gt;
     color: &amp;quot;white&amp;quot;;&lt;br /&gt;
 }&lt;br /&gt;
 /* Define a style for the page-up and page-down buttons */&lt;br /&gt;
 QScrollBar::add-line:vertical,&lt;br /&gt;
 QScrollBar::sub-line:vertical,&lt;br /&gt;
 QScrollBar::add-line:horizontal,&lt;br /&gt;
 QScrollBar::sub-line:horizontal {&lt;br /&gt;
     background: #CCCCCC; /* Set the background color */&lt;br /&gt;
 }&lt;br /&gt;
 /* Define a style for the page-up and page-down buttons when hovered */&lt;br /&gt;
 QScrollBar::add-line:vertical:hover,&lt;br /&gt;
 QScrollBar::sub-line:vertical:hover,&lt;br /&gt;
 QScrollBar::add-line:horizontal:hover,&lt;br /&gt;
 QScrollBar::sub-line:horizontal:hover {&lt;br /&gt;
     background: #999999; /* Set the background color when hovered */&lt;br /&gt;
 }&lt;br /&gt;
 /* Define a style for the arrows of the page-up and page-down buttons */&lt;br /&gt;
 QScrollBar::up-arrow:vertical,&lt;br /&gt;
 QScrollBar::down-arrow:vertical,&lt;br /&gt;
 QScrollBar::up-arrow:horizontal,&lt;br /&gt;
 QScrollBar::down-arrow:horizontal {&lt;br /&gt;
     background: #999999; /* Set the color of the arrow */&lt;br /&gt;
 }&lt;br /&gt;
 /* Define a style for the arrows of the page-up and page-down buttons when hovered */&lt;br /&gt;
 QScrollBar::up-arrow:vertical:hover,&lt;br /&gt;
 QScrollBar::down-arrow:vertical:hover,&lt;br /&gt;
 QScrollBar::up-arrow:horizontal:hover,&lt;br /&gt;
 QScrollBar::down-arrow:horizontal:hover {&lt;br /&gt;
     background: #CCCCCC; /* Set the background color of the arrow when hovered */&lt;br /&gt;
 }&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=Qt_Framework&amp;diff=70</id>
		<title>Qt Framework</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=Qt_Framework&amp;diff=70"/>
		<updated>2025-04-09T07:36:34Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Information Technology]]&lt;br /&gt;
== Tool Workarounds ==&lt;br /&gt;
&lt;br /&gt;
=== Creator ===&lt;br /&gt;
The Creator IDE still does not implement a style plugin, which, makes improving the contrast of widgets to be more difficult. The scrollbars still could have greater contrast. I&#039;ve used this stylesheet file, shown below, and passed it to the &amp;quot;-stylesheet&amp;quot; option to creator when launching it:&lt;br /&gt;
&lt;br /&gt;
 /* Define a style for the vertical scrollbar */&lt;br /&gt;
 QScrollBar:vertical {&lt;br /&gt;
     background: #3f3f3f; /* Set the background color */&lt;br /&gt;
 }&lt;br /&gt;
 /* Define a style for the horizontal scrollbar */&lt;br /&gt;
 QScrollBar:horizontal {&lt;br /&gt;
     background: #3f3f3f; /* Set the background color */&lt;br /&gt;
     &lt;br /&gt;
 }&lt;br /&gt;
 /* Define a style for the handle (the draggable part) of the scrollbar */&lt;br /&gt;
 QScrollBar::handle:vertical,&lt;br /&gt;
 QScrollBar::handle:horizontal {&lt;br /&gt;
     background: #999999; /* Set the color of the handle */&lt;br /&gt;
     min-height: 20px; /* Set the minimum height of the handle */&lt;br /&gt;
 }&lt;br /&gt;
 QLabel::Link, QLabel::LinkVisited {&lt;br /&gt;
     color: &amp;quot;white&amp;quot;;&lt;br /&gt;
 }&lt;br /&gt;
 /* Define a style for the page-up and page-down buttons */&lt;br /&gt;
 QScrollBar::add-line:vertical,&lt;br /&gt;
 QScrollBar::sub-line:vertical,&lt;br /&gt;
 QScrollBar::add-line:horizontal,&lt;br /&gt;
 QScrollBar::sub-line:horizontal {&lt;br /&gt;
     background: #CCCCCC; /* Set the background color */&lt;br /&gt;
 }&lt;br /&gt;
 /* Define a style for the page-up and page-down buttons when hovered */&lt;br /&gt;
 QScrollBar::add-line:vertical:hover,&lt;br /&gt;
 QScrollBar::sub-line:vertical:hover,&lt;br /&gt;
 QScrollBar::add-line:horizontal:hover,&lt;br /&gt;
 QScrollBar::sub-line:horizontal:hover {&lt;br /&gt;
     background: #999999; /* Set the background color when hovered */&lt;br /&gt;
 }&lt;br /&gt;
 /* Define a style for the arrows of the page-up and page-down buttons */&lt;br /&gt;
 QScrollBar::up-arrow:vertical,&lt;br /&gt;
 QScrollBar::down-arrow:vertical,&lt;br /&gt;
 QScrollBar::up-arrow:horizontal,&lt;br /&gt;
 QScrollBar::down-arrow:horizontal {&lt;br /&gt;
     background: #999999; /* Set the color of the arrow */&lt;br /&gt;
 }&lt;br /&gt;
 /* Define a style for the arrows of the page-up and page-down buttons when hovered */&lt;br /&gt;
 QScrollBar::up-arrow:vertical:hover,&lt;br /&gt;
 QScrollBar::down-arrow:vertical:hover,&lt;br /&gt;
 QScrollBar::up-arrow:horizontal:hover,&lt;br /&gt;
 QScrollBar::down-arrow:horizontal:hover {&lt;br /&gt;
     background: #CCCCCC; /* Set the background color of the arrow when hovered */&lt;br /&gt;
 }&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=Microsoft_Windows/Workarounds_and_Fixes&amp;diff=69</id>
		<title>Microsoft Windows/Workarounds and Fixes</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=Microsoft_Windows/Workarounds_and_Fixes&amp;diff=69"/>
		<updated>2025-04-09T07:36:09Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Information Technology|Microsoft Windows]]&lt;br /&gt;
&lt;br /&gt;
== Storage ==&lt;br /&gt;
&lt;br /&gt;
=== Unable to Remove a Busy Volume ===&lt;br /&gt;
When you try to safely remove a mass storage device, and you get a dialog box stating that the device is busy, you can either wait till any pending writes finish, or you can see which process is holding it up. &lt;br /&gt;
&lt;br /&gt;
Bring up the Run Dialog with &#039;&#039;&#039;Windows Key + R,&#039;&#039;&#039; then type &amp;quot;resmon&amp;quot;. Press enter, Go to the CPU tab, and expand the section titled &amp;quot;Associated Handles&amp;quot;. In the search box, type in the drive letter of the mass storage device, to reveal which process is holding it up. You can then choose to end the process with Task Manager.&lt;br /&gt;
&lt;br /&gt;
== Printers ==&lt;br /&gt;
&lt;br /&gt;
=== Authentication Issues when trying to Access a Shared Printer ===&lt;br /&gt;
In recent version of Windows 11, user authentication is required for printer sharing, and the account used to authenticate with must exist on the clients as well. Follow these steps (taken from https://learn.microsoft.com/en-us/answers/questions/1168568/error-credentials-supplied-are-not-sufficient-when, by user &#039;&#039;Don Baker&#039;&#039;):&amp;lt;blockquote&amp;gt;I was struggling with the same issue.  I tried everything. Turning off password protected printing, modifying registry keys etc. Everything the Internet had to offer.&lt;br /&gt;
&lt;br /&gt;
# On the Windows 11 computer where the printer is shared, create a local user (lusrmgr.msc) I created a user named &amp;quot;printer&amp;quot; and gave it a password.&lt;br /&gt;
# On the Windows 10/11 computer you are trying to print from, open Control Panel &amp;gt; User Accounts &amp;gt; Windows Credentials. Select Windows Credentials, then select Add Windows Credential.&lt;br /&gt;
# Fill out the fields (server name, user name, password) and click OK.&lt;br /&gt;
&lt;br /&gt;
Now you should be able to add a printer without being prompted for credentials.&amp;lt;/blockquote&amp;gt;Note that this is more for PC&#039;s belonging to the same workgroup. With an domain controller, this issue may not occur.&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=Microsoft_Windows/Useful_Commands&amp;diff=68</id>
		<title>Microsoft Windows/Useful Commands</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=Microsoft_Windows/Useful_Commands&amp;diff=68"/>
		<updated>2025-04-09T07:35:50Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Information Technology|Microsoft Windows]]&lt;br /&gt;
&lt;br /&gt;
== Service Management ==&lt;br /&gt;
Press [Windows Key] + [X}, and click &amp;quot;Terminal (Admin)&amp;quot; to bring up PowerShell or the Command Prompt in elevated mode.&lt;br /&gt;
&lt;br /&gt;
=== Search for a Service ===&lt;br /&gt;
 sc query | findstr /I &amp;quot;docker&amp;quot;&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Workarounds&amp;diff=67</id>
		<title>GNU Linux/Workarounds</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Workarounds&amp;diff=67"/>
		<updated>2025-04-09T07:35:21Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Information Technology|GNU Linux]]&lt;br /&gt;
A lot of distributions come fairly close to being perfect, but sometimes default configurations or behaviors need to be adjusted to work for certain scenarios. Please consult the help material that accompanies the tools referenced below, if you need a better understanding of their functionalities or behaviors, and whether or not these fixes are appropriate for your use cases.&lt;br /&gt;
&lt;br /&gt;
== Networking ==&lt;br /&gt;
&lt;br /&gt;
=== WiFi Hotspot Issues ===&lt;br /&gt;
&lt;br /&gt;
==== Clients Unable to Get Internet Access ====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;I recommend just having iptables as a firewall alone, and not in combination with, other firewalls. After writing this, I found that no rules in iptables chains were necessary for my client to connect to my WiFi hotspot. Add the rules below, as a last resort.&amp;lt;/blockquote&amp;gt;In my case, after installing Docker on endeavourOS, I found that my hotspot could be connected to, but, the client was unable to obtain an IP address. I was using GNOME&#039;s settings applet, which is a wrapper for NetworkManager.&lt;br /&gt;
&lt;br /&gt;
Luckily, iptables, the firewall built into Linux, can be used. Based on hints provided by (https://wiki.archlinux.org/title/Internet_sharing#With_iptables)[https://wiki.archlinux.org/title/Internet_sharing#With_iptables], I could add a link level packet filter with NAT, using something similar to the these commands (with superuser privileges):&lt;br /&gt;
&lt;br /&gt;
 iptables -t nat -A POSTROUTING -o &amp;lt;ethernet interface name&amp;gt; -j MASQUERADE&lt;br /&gt;
 iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT&lt;br /&gt;
 iptables -A FORWARD -i &amp;lt;wifi adapter name&amp;gt; -o &amp;lt;ethernet interface name&amp;gt; -j ACCEPT&lt;br /&gt;
&lt;br /&gt;
Note: Network interfaces can be listed with the &amp;quot;ifconfig&amp;quot; program.&lt;br /&gt;
&lt;br /&gt;
If clients are still unable to gain internet access after connecting to the hotspot, try disabling firewalld (this is because, as a RedHat blog article points out, it can conflict with iptables: https://www.redhat.com/en/blog/iptables). &lt;br /&gt;
&lt;br /&gt;
== GPU&#039;s ==&lt;br /&gt;
&lt;br /&gt;
=== Wayland User Experience ===&lt;br /&gt;
==== Lag with NVIDIA GPU&#039;s ====&lt;br /&gt;
If you have an AMD graphics card, either integrated or dedicated, you will likely be accustomed to having a better user experience than those with NVIDIA graphics cards.&lt;br /&gt;
&lt;br /&gt;
Wayland works pretty well, but memory and other clock settings stay at too low of a frequency, causing lag. This is noticeable with the GNOME desktop shell. I use this code below to increase the minimum clock speeds on my dedicated GPU.&lt;br /&gt;
 sudo nvidia-smi -pm 1&lt;br /&gt;
 sudo nvidia-smi -lmc 1000,6000&lt;br /&gt;
 sudo nvidia-smi -lgc 1000,2000&lt;br /&gt;
The first command enables the persistence mode daemon, which keeps the kernel mode driver running (even when no other application is actively using it), the second locks the memory clock between 1000 and 6000 MHz, and the last, locks the graphics clock to be between 1000 and 2000 MHz. The command line arguments cannot be combined into one invocation, as nvidia-smi will not allow it.&lt;br /&gt;
&lt;br /&gt;
I&#039;ve found it useful to have a systemd service to do this automatically, when the system starts. I have written a file located here: &#039;&#039;&#039;/etc/systemd/system/nvidia-fix-clocks.service:&#039;&#039;&#039;&lt;br /&gt;
 [Unit]&lt;br /&gt;
 Description=Boost NVIDIA GPU memory and graphics clock speeds&lt;br /&gt;
 &lt;br /&gt;
 [Service]&lt;br /&gt;
 Type=oneshot&lt;br /&gt;
 ExecStart=/opt/ScriptFixes/nv_fix_clocks.sh&lt;br /&gt;
 &lt;br /&gt;
 [Install]&lt;br /&gt;
 WantedBy=multi-user.target&lt;br /&gt;
Don&#039;t forget to reload systemd&#039;s daemon with &#039;&#039;&#039;systemctl reload-daemon&#039;&#039;&#039;, and to enable the service with &#039;&#039;&#039;systemctl enable nvidia-fix-clocks.service&#039;&#039;&#039;. The changes will apply on the next reboot.&lt;br /&gt;
&lt;br /&gt;
==== OpenGL/X11 Application Not Running With a Dedicated NVIDIA GPU ====&lt;br /&gt;
I encountered this issue when running &#039;&#039;Freecad,&#039;&#039; which, in my case, could not use my dedicated GPU due to initialization issues with the OpenGL Extension for X11 (GLX). I use this code below, within a script, to ensure Freecad&#039;s rendering path goes a different way:&lt;br /&gt;
 Xwayland -decorate -geometry 1920x1080 :2 &amp;amp;&lt;br /&gt;
 QT_QPA_PLATFORM=xcb prime-run freecad -display :2&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Useful_Commands&amp;diff=66</id>
		<title>GNU Linux/Useful Commands</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Useful_Commands&amp;diff=66"/>
		<updated>2025-04-09T07:35:01Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Information Technology|GNU Linux]]&lt;br /&gt;
&lt;br /&gt;
== File Conversion ==&lt;br /&gt;
&lt;br /&gt;
=== Batch Convert Man Pages into HTML files ===&lt;br /&gt;
Requires the &amp;lt;code&amp;gt;mandoc&amp;lt;/code&amp;gt; program to be installed.&lt;br /&gt;
 &amp;lt;code&amp;gt;mkdir html &amp;amp;&amp;amp; for x in .; do mandoc -Thtml -O man=./html/%N.%S.html,toc $x &amp;gt; html/$x.html; done&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Virtual Machines ==&lt;br /&gt;
I&#039;ve found this to be more useful than &amp;lt;code&amp;gt;guestmount&amp;lt;/code&amp;gt; (provided by the &amp;lt;code&amp;gt;libguestfs-tools&amp;lt;/code&amp;gt; package for Ubuntu), because it does not require superuser privileges to execute, and is easy to unmount afterwards. Based on the answer provided on Super User: &amp;lt;nowiki&amp;gt;https://superuser.com/a/1548983&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
 &amp;lt;code&amp;gt;mkdir -p ~/tmp/windows10-vm&lt;br /&gt;
 nbdfuse ~/tmp/windows10-vm [ qemu-nbd path_to_disk_image ] &amp;amp;&lt;br /&gt;
 fusermount -u ~/tmp/windows10-vm&amp;lt;/code&amp;gt;&lt;br /&gt;
An alternative is to let QEMU mount the virtual machine disk image with the NBD driver. Enable the nbd kernel module, mount the image, and then mount the partition with flags to make it accessible to other users without superuser privileges. &lt;br /&gt;
&lt;br /&gt;
With fdisk, you can identify the device file pertaining to the partition you want to mount (I&#039;ve used /dev/nbd0p1 for example). The dmask and fmask, are for the octal permission bits of directories and files.&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to run umount when finished.&lt;br /&gt;
 modprobe nbd&lt;br /&gt;
 qemu-nbd --connect=/dev/nbd0 &amp;lt;path to VM disk image&amp;gt;&lt;br /&gt;
 fdisk -l /dev/nbd0&lt;br /&gt;
 mount /dev/nbd0p1 /mnt/vhd1 -o dmask=000,fmask=000&lt;br /&gt;
 umount /mnt/vhd1&lt;br /&gt;
&lt;br /&gt;
== NVIDIA ==&lt;br /&gt;
To workaround a bug where the frame rate drops for Mutter and other applications, when they are viewed on an external monitor, boost the memory clock speed with this command below. The two values after lmc are the minimum and maximum memory clock speeds in MHz.&lt;br /&gt;
 sudo nvidia-smi -lmc 2000,6000&lt;br /&gt;
&lt;br /&gt;
== Making Changes to Windows Registry Hive Files ==&lt;br /&gt;
&#039;&#039;&#039;NB: It is recommended that you should make backup copies of any hive files you intend to edit, and store them on a separate partition.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The Windows registry consists of keys and values, belonging to hives. These hives are stored under &amp;lt;code&amp;gt;C:\Windows\system32\config&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
According to Microsoft&#039;s official documentation (https://learn.microsoft.com/en-us/windows/win32/sysinfo/registry-hives), these are the root keys and the hive file names which they correspond to:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Registry hive&lt;br /&gt;
!Supporting files&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_CURRENT_CONFIG&#039;&#039;&#039;&lt;br /&gt;
|System, System.alt, System.log, System.sav&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_CURRENT_USER&#039;&#039;&#039;&lt;br /&gt;
|Ntuser.dat, Ntuser.dat.log&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_LOCAL_MACHINE\SAM&#039;&#039;&#039;&lt;br /&gt;
|Sam, Sam.log, Sam.sav&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_LOCAL_MACHINE\Security&#039;&#039;&#039;&lt;br /&gt;
|Security, Security.log, Security.sav&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_LOCAL_MACHINE\Software&#039;&#039;&#039;&lt;br /&gt;
|Software, Software.log, Software.sav&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_LOCAL_MACHINE\System&#039;&#039;&#039;&lt;br /&gt;
|System, System.alt, System.log, System.sav&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_USERS\.DEFAULT&#039;&#039;&#039;&lt;br /&gt;
|Default, Default.log, Default.sav&lt;br /&gt;
|}I find it useful to browse through sub-keys and values with &amp;lt;code&amp;gt;hivexsh &amp;lt;path to hive&amp;gt;&amp;lt;/code&amp;gt; , then export a key from the hive file (using the file for  HKEY_LOCAL_MACHINE\Software for example): &lt;br /&gt;
 &amp;lt;code&amp;gt;hivexregedit --export ./SOFTWARE Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer &amp;gt; explorer-policies.reg&amp;lt;/code&amp;gt;&lt;br /&gt;
 &amp;lt;code&amp;gt;&lt;br /&gt;
 hivexregedit --merge ./SOFTWARE ./explorer-policies.reg&amp;lt;/code&amp;gt;&lt;br /&gt;
I&#039;ve left out the conversion of the exported registry file from Windows UTF-16 to UTF-8, and back again to UTF-16 before the merge, as I&#039;ve found through testing that this isn&#039;t needed (with hivex version 1.3.23).&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=Main_Page&amp;diff=65</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=Main_Page&amp;diff=65"/>
		<updated>2025-04-09T07:33:26Z</updated>

		<summary type="html">&lt;p&gt;Root: /* Directory */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://www.bgcottrell.com &amp;lt; Go back to bgcottrell.com]&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;Strong&amp;gt;Welcome&amp;lt;/Strong&amp;gt; ==&lt;br /&gt;
This is a place to store gathered ideas, providing a knowledge base, and more, sharing pieces of information that I&#039;ve found useful.&lt;br /&gt;
&lt;br /&gt;
=== Directory ===&lt;br /&gt;
&amp;lt;categorytree mode=&amp;quot;all&amp;quot; depth=&amp;quot;6&amp;quot;&amp;gt;Information Technology&amp;lt;/categorytree&amp;gt;&lt;br /&gt;
&amp;lt;categorytree mode=&amp;quot;all&amp;quot; depth=&amp;quot;6&amp;quot;&amp;gt;Food&amp;lt;/categorytree&amp;gt;&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=Category:Knowledge_Base&amp;diff=64</id>
		<title>Category:Knowledge Base</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=Category:Knowledge_Base&amp;diff=64"/>
		<updated>2025-04-09T07:33:05Z</updated>

		<summary type="html">&lt;p&gt;Root: Root moved page Category:Knowledge Base to Category:Information Technology&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[:Category:Information Technology]]&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=Category:Information_Technology&amp;diff=63</id>
		<title>Category:Information Technology</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=Category:Information_Technology&amp;diff=63"/>
		<updated>2025-04-09T07:33:05Z</updated>

		<summary type="html">&lt;p&gt;Root: Root moved page Category:Knowledge Base to Category:Information Technology&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Knowledge Base ==&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=Microsoft_Windows/Workarounds_and_Fixes&amp;diff=62</id>
		<title>Microsoft Windows/Workarounds and Fixes</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=Microsoft_Windows/Workarounds_and_Fixes&amp;diff=62"/>
		<updated>2025-03-31T07:04:52Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Knowledge Base|Microsoft Windows]]&lt;br /&gt;
&lt;br /&gt;
== Storage ==&lt;br /&gt;
&lt;br /&gt;
=== Unable to Remove a Busy Volume ===&lt;br /&gt;
When you try to safely remove a mass storage device, and you get a dialog box stating that the device is busy, you can either wait till any pending writes finish, or you can see which process is holding it up. &lt;br /&gt;
&lt;br /&gt;
Bring up the Run Dialog with &#039;&#039;&#039;Windows Key + R,&#039;&#039;&#039; then type &amp;quot;resmon&amp;quot;. Press enter, Go to the CPU tab, and expand the section titled &amp;quot;Associated Handles&amp;quot;. In the search box, type in the drive letter of the mass storage device, to reveal which process is holding it up. You can then choose to end the process with Task Manager.&lt;br /&gt;
&lt;br /&gt;
== Printers ==&lt;br /&gt;
&lt;br /&gt;
=== Authentication Issues when trying to Access a Shared Printer ===&lt;br /&gt;
In recent version of Windows 11, user authentication is required for printer sharing, and the account used to authenticate with must exist on the clients as well. Follow these steps (taken from https://learn.microsoft.com/en-us/answers/questions/1168568/error-credentials-supplied-are-not-sufficient-when, by user &#039;&#039;Don Baker&#039;&#039;):&amp;lt;blockquote&amp;gt;I was struggling with the same issue.  I tried everything. Turning off password protected printing, modifying registry keys etc. Everything the Internet had to offer.&lt;br /&gt;
&lt;br /&gt;
# On the Windows 11 computer where the printer is shared, create a local user (lusrmgr.msc) I created a user named &amp;quot;printer&amp;quot; and gave it a password.&lt;br /&gt;
# On the Windows 10/11 computer you are trying to print from, open Control Panel &amp;gt; User Accounts &amp;gt; Windows Credentials. Select Windows Credentials, then select Add Windows Credential.&lt;br /&gt;
# Fill out the fields (server name, user name, password) and click OK.&lt;br /&gt;
&lt;br /&gt;
Now you should be able to add a printer without being prompted for credentials.&amp;lt;/blockquote&amp;gt;Note that this is more for PC&#039;s belonging to the same workgroup. With an domain controller, this issue may not occur.&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=Microsoft_Windows/Workarounds_and_Fixes&amp;diff=61</id>
		<title>Microsoft Windows/Workarounds and Fixes</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=Microsoft_Windows/Workarounds_and_Fixes&amp;diff=61"/>
		<updated>2025-03-31T06:54:51Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Knowledge Base|Microsoft Windows]]&lt;br /&gt;
&lt;br /&gt;
== Printer Sharing ==&lt;br /&gt;
&lt;br /&gt;
=== Authentication Issues ===&lt;br /&gt;
In recent version of Windows 11, user authentication is required for printer sharing, and the account used to authenticate with must exist on the clients as well. Follow these steps (taken from https://learn.microsoft.com/en-us/answers/questions/1168568/error-credentials-supplied-are-not-sufficient-when, by user &#039;&#039;Don Baker&#039;&#039;):&amp;lt;blockquote&amp;gt;I was struggling with the same issue.  I tried everything. Turning off password protected printing, modifying registry keys etc. Everything the Internet had to offer.&lt;br /&gt;
&lt;br /&gt;
# On the Windows 11 computer where the printer is shared, create a local user (lusrmgr.msc) I created a user named &amp;quot;printer&amp;quot; and gave it a password.&lt;br /&gt;
# On the Windows 10/11 computer you are trying to print from, open Control Panel &amp;gt; User Accounts &amp;gt; Windows Credentials. Select Windows Credentials, then select Add Windows Credential.&lt;br /&gt;
# Fill out the fields (server name, user name, password) and click OK.&lt;br /&gt;
&lt;br /&gt;
Now you should be able to add a printer without being prompted for credentials.&amp;lt;/blockquote&amp;gt;Note that this is more for PC&#039;s belonging to the same workgroup. With an domain controller, this issue may not occur.&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Workarounds&amp;diff=60</id>
		<title>GNU Linux/Workarounds</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Workarounds&amp;diff=60"/>
		<updated>2025-03-31T04:02:55Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Knowledge Base|GNU Linux]]&lt;br /&gt;
A lot of distributions come fairly close to being perfect, but sometimes default configurations or behaviors need to be adjusted to work for certain scenarios. Please consult the help material that accompanies the tools referenced below, if you need a better understanding of their functionalities or behaviors, and whether or not these fixes are appropriate for your use cases.&lt;br /&gt;
&lt;br /&gt;
== Networking ==&lt;br /&gt;
&lt;br /&gt;
=== WiFi Hotspot Issues ===&lt;br /&gt;
&lt;br /&gt;
==== Clients Unable to Get Internet Access ====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;I recommend just having iptables as a firewall alone, and not in combination with, other firewalls. After writing this, I found that no rules in iptables chains were necessary for my client to connect to my WiFi hotspot. Add the rules below, as a last resort.&amp;lt;/blockquote&amp;gt;In my case, after installing Docker on endeavourOS, I found that my hotspot could be connected to, but, the client was unable to obtain an IP address. I was using GNOME&#039;s settings applet, which is a wrapper for NetworkManager.&lt;br /&gt;
&lt;br /&gt;
Luckily, iptables, the firewall built into Linux, can be used. Based on hints provided by (https://wiki.archlinux.org/title/Internet_sharing#With_iptables)[https://wiki.archlinux.org/title/Internet_sharing#With_iptables], I could add a link level packet filter with NAT, using something similar to the these commands (with superuser privileges):&lt;br /&gt;
&lt;br /&gt;
 iptables -t nat -A POSTROUTING -o &amp;lt;ethernet interface name&amp;gt; -j MASQUERADE&lt;br /&gt;
 iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT&lt;br /&gt;
 iptables -A FORWARD -i &amp;lt;wifi adapter name&amp;gt; -o &amp;lt;ethernet interface name&amp;gt; -j ACCEPT&lt;br /&gt;
&lt;br /&gt;
Note: Network interfaces can be listed with the &amp;quot;ifconfig&amp;quot; program.&lt;br /&gt;
&lt;br /&gt;
If clients are still unable to gain internet access after connecting to the hotspot, try disabling firewalld (this is because, as a RedHat blog article points out, it can conflict with iptables: https://www.redhat.com/en/blog/iptables). &lt;br /&gt;
&lt;br /&gt;
== GPU&#039;s ==&lt;br /&gt;
&lt;br /&gt;
=== Wayland User Experience ===&lt;br /&gt;
==== Lag with NVIDIA GPU&#039;s ====&lt;br /&gt;
If you have an AMD graphics card, either integrated or dedicated, you will likely be accustomed to having a better user experience than those with NVIDIA graphics cards.&lt;br /&gt;
&lt;br /&gt;
Wayland works pretty well, but memory and other clock settings stay at too low of a frequency, causing lag. This is noticeable with the GNOME desktop shell. I use this code below to increase the minimum clock speeds on my dedicated GPU.&lt;br /&gt;
 sudo nvidia-smi -pm 1&lt;br /&gt;
 sudo nvidia-smi -lmc 1000,6000&lt;br /&gt;
 sudo nvidia-smi -lgc 1000,2000&lt;br /&gt;
The first command enables the persistence mode daemon, which keeps the kernel mode driver running (even when no other application is actively using it), the second locks the memory clock between 1000 and 6000 MHz, and the last, locks the graphics clock to be between 1000 and 2000 MHz. The command line arguments cannot be combined into one invocation, as nvidia-smi will not allow it.&lt;br /&gt;
&lt;br /&gt;
I&#039;ve found it useful to have a systemd service to do this automatically, when the system starts. I have written a file located here: &#039;&#039;&#039;/etc/systemd/system/nvidia-fix-clocks.service:&#039;&#039;&#039;&lt;br /&gt;
 [Unit]&lt;br /&gt;
 Description=Boost NVIDIA GPU memory and graphics clock speeds&lt;br /&gt;
 &lt;br /&gt;
 [Service]&lt;br /&gt;
 Type=oneshot&lt;br /&gt;
 ExecStart=/opt/ScriptFixes/nv_fix_clocks.sh&lt;br /&gt;
 &lt;br /&gt;
 [Install]&lt;br /&gt;
 WantedBy=multi-user.target&lt;br /&gt;
Don&#039;t forget to reload systemd&#039;s daemon with &#039;&#039;&#039;systemctl reload-daemon&#039;&#039;&#039;, and to enable the service with &#039;&#039;&#039;systemctl enable nvidia-fix-clocks.service&#039;&#039;&#039;. The changes will apply on the next reboot.&lt;br /&gt;
&lt;br /&gt;
==== OpenGL/X11 Application Not Running With a Dedicated NVIDIA GPU ====&lt;br /&gt;
I encountered this issue when running &#039;&#039;Freecad,&#039;&#039; which, in my case, could not use my dedicated GPU due to initialization issues with the OpenGL Extension for X11 (GLX). I use this code below, within a script, to ensure Freecad&#039;s rendering path goes a different way:&lt;br /&gt;
 Xwayland -decorate -geometry 1920x1080 :2 &amp;amp;&lt;br /&gt;
 QT_QPA_PLATFORM=xcb prime-run freecad -display :2&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=Microsoft_Windows/Workarounds_and_Fixes&amp;diff=59</id>
		<title>Microsoft Windows/Workarounds and Fixes</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=Microsoft_Windows/Workarounds_and_Fixes&amp;diff=59"/>
		<updated>2025-03-31T03:55:53Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Knowledge Base|Microsoft Windows]]&lt;br /&gt;
&lt;br /&gt;
== Printer Sharing ==&lt;br /&gt;
&lt;br /&gt;
=== Authentication Issues ===&lt;br /&gt;
In recent version of Windows 11, user authentication is required for printer sharing, and the account used to authenticate with must exist on the clients as well. Follow these steps (taken from https://learn.microsoft.com/en-us/answers/questions/1168568/error-credentials-supplied-are-not-sufficient-when, by user Don Baker):&amp;lt;blockquote&amp;gt;I was struggling with the same issue.  I tried everything. Turning off password protected printing, modifying registry keys etc. Everything the Internet had to offer.&lt;br /&gt;
&lt;br /&gt;
# On the Windows 11 computer where the printer is shared, create a local user (lusrmgr.msc) I created a user named &amp;quot;printer&amp;quot; and gave it a password.&lt;br /&gt;
# On the Windows 10/11 computer you are trying to print from, open Control Panel &amp;gt; User Accounts &amp;gt; Windows Credentials. Select Windows Credentials, then select Add Windows Credential.&lt;br /&gt;
# Fill out the fields (server name, user name, password) and click OK.&lt;br /&gt;
&lt;br /&gt;
Now you should be able to add a printer without being prompted for credentials.&amp;lt;/blockquote&amp;gt;&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Workarounds&amp;diff=58</id>
		<title>GNU Linux/Workarounds</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Workarounds&amp;diff=58"/>
		<updated>2025-03-31T03:52:33Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Knowledge Base|GNU Linux]]&lt;br /&gt;
A lot of distributions come fairly close to being perfect, but sometimes default configurations or behaviors need to be adjusted to work for certain scenarios. Please consult the help material that accompanies the tools referenced below, if you need a better understanding of their functionalities or behaviors, and whether or not these fixes are appropriate for your use cases.&lt;br /&gt;
&lt;br /&gt;
== Networking ==&lt;br /&gt;
&lt;br /&gt;
=== WiFi Hotspot Issues ===&lt;br /&gt;
&lt;br /&gt;
==== Clients Unable to Get Internet Access ====&lt;br /&gt;
In my case, after installing Docker on endeavourOS, I found that my hotspot could be connected to, but, the client was unable to obtain an IP address. I was using GNOME&#039;s settings applet, which is a wrapper for NetworkManager.&lt;br /&gt;
&lt;br /&gt;
Luckily, iptables, the firewall built into Linux, can be used. Based on hints provided by (https://wiki.archlinux.org/title/Internet_sharing#With_iptables)[https://wiki.archlinux.org/title/Internet_sharing#With_iptables], I could add a link level packet filter with NAT, using something similar to the these commands (with superuser privileges):&lt;br /&gt;
&lt;br /&gt;
 iptables -t nat -A POSTROUTING -o &amp;lt;ethernet interface name&amp;gt; -j MASQUERADE&lt;br /&gt;
 iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT&lt;br /&gt;
 iptables -A FORWARD -i &amp;lt;wifi adapter name&amp;gt; -o &amp;lt;ethernet interface name&amp;gt; -j ACCEPT&lt;br /&gt;
&lt;br /&gt;
You can find the network interface names with ifconfig.&lt;br /&gt;
&lt;br /&gt;
If clients are still unable to gain internet access after connecting to the hotspot, try disabling firewalld (this is because, as a RedHat blog article points out, it can conflict with iptables: https://www.redhat.com/en/blog/iptables). After disabling firewalld, I can enable the iptables-based firewall using gufw.&lt;br /&gt;
&lt;br /&gt;
== GPU&#039;s ==&lt;br /&gt;
&lt;br /&gt;
=== Wayland User Experience ===&lt;br /&gt;
==== Lag with NVIDIA GPU&#039;s ====&lt;br /&gt;
If you have an AMD graphics card, either integrated or dedicated, you will likely be accustomed to having a better user experience than those with NVIDIA graphics cards.&lt;br /&gt;
&lt;br /&gt;
Wayland works pretty well, but memory and other clock settings stay at too low of a frequency, causing lag. This is noticeable with the GNOME desktop shell. I use this code below to increase the minimum clock speeds on my dedicated GPU.&lt;br /&gt;
 sudo nvidia-smi -pm 1&lt;br /&gt;
 sudo nvidia-smi -lmc 1000,6000&lt;br /&gt;
 sudo nvidia-smi -lgc 1000,2000&lt;br /&gt;
The first command enables the persistence mode daemon, which keeps the kernel mode driver running (even when no other application is actively using it), the second locks the memory clock between 1000 and 6000 MHz, and the last, locks the graphics clock to be between 1000 and 2000 MHz. The command line arguments cannot be combined into one invocation, as nvidia-smi will not allow it.&lt;br /&gt;
&lt;br /&gt;
I&#039;ve found it useful to have a systemd service to do this automatically, when the system starts. I have written a file located here: &#039;&#039;&#039;/etc/systemd/system/nvidia-fix-clocks.service:&#039;&#039;&#039;&lt;br /&gt;
 [Unit]&lt;br /&gt;
 Description=Boost NVIDIA GPU memory and graphics clock speeds&lt;br /&gt;
 &lt;br /&gt;
 [Service]&lt;br /&gt;
 Type=oneshot&lt;br /&gt;
 ExecStart=/opt/ScriptFixes/nv_fix_clocks.sh&lt;br /&gt;
 &lt;br /&gt;
 [Install]&lt;br /&gt;
 WantedBy=multi-user.target&lt;br /&gt;
Don&#039;t forget to reload systemd&#039;s daemon with &#039;&#039;&#039;systemctl reload-daemon&#039;&#039;&#039;, and to enable the service with &#039;&#039;&#039;systemctl enable nvidia-fix-clocks.service&#039;&#039;&#039;. The changes will apply on the next reboot.&lt;br /&gt;
&lt;br /&gt;
==== OpenGL/X11 Application Not Running With a Dedicated NVIDIA GPU ====&lt;br /&gt;
I encountered this issue when running &#039;&#039;Freecad,&#039;&#039; which, in my case, could not use my dedicated GPU due to initialization issues with the OpenGL Extension for X11 (GLX). I use this code below, within a script, to ensure Freecad&#039;s rendering path goes a different way:&lt;br /&gt;
 Xwayland -decorate -geometry 1920x1080 :2 &amp;amp;&lt;br /&gt;
 QT_QPA_PLATFORM=xcb prime-run freecad -display :2&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=Microsoft_Windows/Useful_Commands&amp;diff=57</id>
		<title>Microsoft Windows/Useful Commands</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=Microsoft_Windows/Useful_Commands&amp;diff=57"/>
		<updated>2025-03-31T03:52:05Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Knowledge Base|Microsoft Windows]]&lt;br /&gt;
&lt;br /&gt;
== Service Management ==&lt;br /&gt;
Press [Windows Key] + [X}, and click &amp;quot;Terminal (Admin)&amp;quot; to bring up PowerShell or the Command Prompt in elevated mode.&lt;br /&gt;
&lt;br /&gt;
=== Search for a Service ===&lt;br /&gt;
 sc query | findstr /I &amp;quot;docker&amp;quot;&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=Microsoft_Windows/Workarounds_and_Fixes&amp;diff=56</id>
		<title>Microsoft Windows/Workarounds and Fixes</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=Microsoft_Windows/Workarounds_and_Fixes&amp;diff=56"/>
		<updated>2025-03-31T03:51:38Z</updated>

		<summary type="html">&lt;p&gt;Root: Created page with &amp;quot;Microsoft Windows&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Knowledge Base|Microsoft Windows]]&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Workarounds&amp;diff=55</id>
		<title>GNU Linux/Workarounds</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Workarounds&amp;diff=55"/>
		<updated>2025-03-15T04:20:41Z</updated>

		<summary type="html">&lt;p&gt;Root: /* Broken IP Configuration */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Knowledge Base]]&lt;br /&gt;
A lot of distributions come fairly close to being perfect, but sometimes default configurations or behaviors need to be adjusted to work for certain scenarios. Please consult the help material that accompanies the tools referenced below, if you need a better understanding of their functionalities or behaviors, and whether or not these fixes are appropriate for your use cases.&lt;br /&gt;
&lt;br /&gt;
== Networking ==&lt;br /&gt;
&lt;br /&gt;
=== WiFi Hotspot Issues ===&lt;br /&gt;
&lt;br /&gt;
==== Clients Unable to Get Internet Access ====&lt;br /&gt;
In my case, after installing Docker on endeavourOS, I found that my hotspot could be connected to, but, the client was unable to obtain an IP address. I was using GNOME&#039;s settings applet, which is a wrapper for NetworkManager.&lt;br /&gt;
&lt;br /&gt;
Luckily, iptables, the firewall built into Linux, can be used. Based on hints provided by (https://wiki.archlinux.org/title/Internet_sharing#With_iptables)[https://wiki.archlinux.org/title/Internet_sharing#With_iptables], I could add a link level packet filter with NAT, using something similar to the these commands (with superuser privileges):&lt;br /&gt;
&lt;br /&gt;
 iptables -t nat -A POSTROUTING -o &amp;lt;ethernet interface name&amp;gt; -j MASQUERADE&lt;br /&gt;
 iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT&lt;br /&gt;
 iptables -A FORWARD -i &amp;lt;wifi adapter name&amp;gt; -o &amp;lt;ethernet interface name&amp;gt; -j ACCEPT&lt;br /&gt;
&lt;br /&gt;
You can find the network interface names with ifconfig.&lt;br /&gt;
&lt;br /&gt;
If clients are still unable to gain internet access after connecting to the hotspot, try disabling firewalld (this is because, as a RedHat blog article points out, it can conflict with iptables: https://www.redhat.com/en/blog/iptables). After disabling firewalld, I can enable the iptables-based firewall using gufw.&lt;br /&gt;
&lt;br /&gt;
== GPU&#039;s ==&lt;br /&gt;
&lt;br /&gt;
=== Wayland User Experience ===&lt;br /&gt;
==== Lag with NVIDIA GPU&#039;s ====&lt;br /&gt;
If you have an AMD graphics card, either integrated or dedicated, you will likely be accustomed to having a better user experience than those with NVIDIA graphics cards.&lt;br /&gt;
&lt;br /&gt;
Wayland works pretty well, but memory and other clock settings stay at too low of a frequency, causing lag. This is noticeable with the GNOME desktop shell. I use this code below to increase the minimum clock speeds on my dedicated GPU.&lt;br /&gt;
 sudo nvidia-smi -pm 1&lt;br /&gt;
 sudo nvidia-smi -lmc 1000,6000&lt;br /&gt;
 sudo nvidia-smi -lgc 1000,2000&lt;br /&gt;
The first command enables the persistence mode daemon, which keeps the kernel mode driver running (even when no other application is actively using it), the second locks the memory clock between 1000 and 6000 MHz, and the last, locks the graphics clock to be between 1000 and 2000 MHz. The command line arguments cannot be combined into one invocation, as nvidia-smi will not allow it.&lt;br /&gt;
&lt;br /&gt;
I&#039;ve found it useful to have a systemd service to do this automatically, when the system starts. I have written a file located here: &#039;&#039;&#039;/etc/systemd/system/nvidia-fix-clocks.service:&#039;&#039;&#039;&lt;br /&gt;
 [Unit]&lt;br /&gt;
 Description=Boost NVIDIA GPU memory and graphics clock speeds&lt;br /&gt;
 &lt;br /&gt;
 [Service]&lt;br /&gt;
 Type=oneshot&lt;br /&gt;
 ExecStart=/opt/ScriptFixes/nv_fix_clocks.sh&lt;br /&gt;
 &lt;br /&gt;
 [Install]&lt;br /&gt;
 WantedBy=multi-user.target&lt;br /&gt;
Don&#039;t forget to reload systemd&#039;s daemon with &#039;&#039;&#039;systemctl reload-daemon&#039;&#039;&#039;, and to enable the service with &#039;&#039;&#039;systemctl enable nvidia-fix-clocks.service&#039;&#039;&#039;. The changes will apply on the next reboot.&lt;br /&gt;
&lt;br /&gt;
==== OpenGL/X11 Application Not Running With a Dedicated NVIDIA GPU ====&lt;br /&gt;
I encountered this issue when running &#039;&#039;Freecad,&#039;&#039; which, in my case, could not use my dedicated GPU due to initialization issues with the OpenGL Extension for X11 (GLX). I use this code below, within a script, to ensure Freecad&#039;s rendering path goes a different way:&lt;br /&gt;
 Xwayland -decorate -geometry 1920x1080 :2 &amp;amp;&lt;br /&gt;
 QT_QPA_PLATFORM=xcb prime-run freecad -display :2&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Workarounds&amp;diff=54</id>
		<title>GNU Linux/Workarounds</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Workarounds&amp;diff=54"/>
		<updated>2025-03-13T23:37:44Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Knowledge Base]]&lt;br /&gt;
A lot of distributions come fairly close to being perfect, but sometimes default configurations or behaviors need to be adjusted to work for certain scenarios. Please consult the help material that accompanies the tools referenced below, if you need a better understanding of their functionalities or behaviors, and whether or not these fixes are appropriate for your use cases.&lt;br /&gt;
&lt;br /&gt;
== Networking ==&lt;br /&gt;
&lt;br /&gt;
=== WiFi Hotspot Issues ===&lt;br /&gt;
&lt;br /&gt;
==== Broken IP Configuration ====&lt;br /&gt;
In my case, after installing Docker on endeavourOS, I found that my hotspot could be connected to, but, the client was unable to obtain an IP address. I was using GNOME&#039;s settings applet, which is a wrapper for NetworkManager.&lt;br /&gt;
&lt;br /&gt;
Luckily, using iptables, based on hints provided by (https://wiki.archlinux.org/title/Internet_sharing#With_iptables)[https://wiki.archlinux.org/title/Internet_sharing#With_iptables], I could add a link level packet filter with NAT, using something similar to the these commands (with superuser privileges):&lt;br /&gt;
&lt;br /&gt;
 iptables -t nat -A POSTROUTING -o &amp;lt;ethernet interface name&amp;gt; -j MASQUERADE&lt;br /&gt;
 iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT&lt;br /&gt;
 iptables -A FORWARD -i &amp;lt;wifi adapter name&amp;gt; -o &amp;lt;ethernet interface name&amp;gt; -j ACCEPT&lt;br /&gt;
&lt;br /&gt;
You can find the network interface names with ifconfig.&lt;br /&gt;
&lt;br /&gt;
== GPU&#039;s ==&lt;br /&gt;
&lt;br /&gt;
=== Wayland User Experience ===&lt;br /&gt;
==== Lag with NVIDIA GPU&#039;s ====&lt;br /&gt;
If you have an AMD graphics card, either integrated or dedicated, you will likely be accustomed to having a better user experience than those with NVIDIA graphics cards.&lt;br /&gt;
&lt;br /&gt;
Wayland works pretty well, but memory and other clock settings stay at too low of a frequency, causing lag. This is noticeable with the GNOME desktop shell. I use this code below to increase the minimum clock speeds on my dedicated GPU.&lt;br /&gt;
 sudo nvidia-smi -pm 1&lt;br /&gt;
 sudo nvidia-smi -lmc 1000,6000&lt;br /&gt;
 sudo nvidia-smi -lgc 1000,2000&lt;br /&gt;
The first command enables the persistence mode daemon, which keeps the kernel mode driver running (even when no other application is actively using it), the second locks the memory clock between 1000 and 6000 MHz, and the last, locks the graphics clock to be between 1000 and 2000 MHz. The command line arguments cannot be combined into one invocation, as nvidia-smi will not allow it.&lt;br /&gt;
&lt;br /&gt;
I&#039;ve found it useful to have a systemd service to do this automatically, when the system starts. I have written a file located here: &#039;&#039;&#039;/etc/systemd/system/nvidia-fix-clocks.service:&#039;&#039;&#039;&lt;br /&gt;
 [Unit]&lt;br /&gt;
 Description=Boost NVIDIA GPU memory and graphics clock speeds&lt;br /&gt;
 &lt;br /&gt;
 [Service]&lt;br /&gt;
 Type=oneshot&lt;br /&gt;
 ExecStart=/opt/ScriptFixes/nv_fix_clocks.sh&lt;br /&gt;
 &lt;br /&gt;
 [Install]&lt;br /&gt;
 WantedBy=multi-user.target&lt;br /&gt;
Don&#039;t forget to reload systemd&#039;s daemon with &#039;&#039;&#039;systemctl reload-daemon&#039;&#039;&#039;, and to enable the service with &#039;&#039;&#039;systemctl enable nvidia-fix-clocks.service&#039;&#039;&#039;. The changes will apply on the next reboot.&lt;br /&gt;
&lt;br /&gt;
==== OpenGL/X11 Application Not Running With a Dedicated NVIDIA GPU ====&lt;br /&gt;
I encountered this issue when running &#039;&#039;Freecad,&#039;&#039; which, in my case, could not use my dedicated GPU due to initialization issues with the OpenGL Extension for X11 (GLX). I use this code below, within a script, to ensure Freecad&#039;s rendering path goes a different way:&lt;br /&gt;
 Xwayland -decorate -geometry 1920x1080 :2 &amp;amp;&lt;br /&gt;
 QT_QPA_PLATFORM=xcb prime-run freecad -display :2&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Workarounds&amp;diff=53</id>
		<title>GNU Linux/Workarounds</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Workarounds&amp;diff=53"/>
		<updated>2025-03-13T23:32:45Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Knowledge Base]]&lt;br /&gt;
A lot of distributions come fairly close to being perfect, but sometimes workarounds are required to improve the user experience. Please note that these are filed under distribution and driver specific sections, so may or may not be suitable for other combinations.&lt;br /&gt;
&lt;br /&gt;
== Networking ==&lt;br /&gt;
&lt;br /&gt;
=== WiFi Hotspot Issues ===&lt;br /&gt;
&lt;br /&gt;
==== Broken IP Configuration ====&lt;br /&gt;
In my case, after installing Docker on endeavourOS, I found that my hotspot could be connected to, but, the client was unable to obtain an IP address. I was using GNOME&#039;s settings applet, which is a wrapper for NetworkManager.&lt;br /&gt;
&lt;br /&gt;
Luckily, using iptables, based on hints provided by (https://wiki.archlinux.org/title/Internet_sharing#With_iptables)[https://wiki.archlinux.org/title/Internet_sharing#With_iptables], I could add a link level packet filter with NAT, using something similar to the these commands (with superuser privileges):&lt;br /&gt;
&lt;br /&gt;
 iptables -t nat -A POSTROUTING -o &amp;lt;ethernet interface name&amp;gt; -j MASQUERADE&lt;br /&gt;
 iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT&lt;br /&gt;
 iptables -A FORWARD -i &amp;lt;wifi adapter name&amp;gt; -o &amp;lt;ethernet interface name&amp;gt; -j ACCEPT&lt;br /&gt;
&lt;br /&gt;
You can find the network interface names with ifconfig.&lt;br /&gt;
&lt;br /&gt;
== GPU&#039;s ==&lt;br /&gt;
&lt;br /&gt;
=== Wayland User Experience ===&lt;br /&gt;
==== Lag with NVIDIA GPU&#039;s ====&lt;br /&gt;
If you have an AMD graphics card, either integrated or dedicated, you will likely be accustomed to having a better user experience than those with NVIDIA graphics cards.&lt;br /&gt;
&lt;br /&gt;
Wayland works pretty well, but memory and other clock settings stay at too low of a frequency, causing lag. This is noticeable with the GNOME desktop shell. I use this code below to increase the minimum clock speeds on my dedicated GPU.&lt;br /&gt;
 sudo nvidia-smi -pm 1&lt;br /&gt;
 sudo nvidia-smi -lmc 1000,6000&lt;br /&gt;
 sudo nvidia-smi -lgc 1000,2000&lt;br /&gt;
The first command enables the persistence mode daemon, which keeps the kernel mode driver running (even when no other application is actively using it), the second locks the memory clock between 1000 and 6000 MHz, and the last, locks the graphics clock to be between 1000 and 2000 MHz. The command line arguments cannot be combined into one invocation, as nvidia-smi will not allow it.&lt;br /&gt;
&lt;br /&gt;
I&#039;ve found it useful to have a systemd service to do this automatically, when the system starts. I have written a file located here: &#039;&#039;&#039;/etc/systemd/system/nvidia-fix-clocks.service:&#039;&#039;&#039;&lt;br /&gt;
 [Unit]&lt;br /&gt;
 Description=Boost NVIDIA GPU memory and graphics clock speeds&lt;br /&gt;
 &lt;br /&gt;
 [Service]&lt;br /&gt;
 Type=oneshot&lt;br /&gt;
 ExecStart=/opt/ScriptFixes/nv_fix_clocks.sh&lt;br /&gt;
 &lt;br /&gt;
 [Install]&lt;br /&gt;
 WantedBy=multi-user.target&lt;br /&gt;
Don&#039;t forget to reload systemd&#039;s daemon with &#039;&#039;&#039;systemctl reload-daemon&#039;&#039;&#039;, and to enable the service with &#039;&#039;&#039;systemctl enable nvidia-fix-clocks.service&#039;&#039;&#039;. The changes will apply on the next reboot.&lt;br /&gt;
&lt;br /&gt;
==== OpenGL/X11 Application Not Running With a Dedicated NVIDIA GPU ====&lt;br /&gt;
I encountered this issue when running &#039;&#039;Freecad,&#039;&#039; which, in my case, could not use my dedicated GPU due to initialization issues with the OpenGL Extension for X11 (GLX). I use this code below, within a script, to ensure Freecad&#039;s rendering path goes a different way:&lt;br /&gt;
 Xwayland -decorate -geometry 1920x1080 :2 &amp;amp;&lt;br /&gt;
 QT_QPA_PLATFORM=xcb prime-run freecad -display :2&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Workarounds&amp;diff=52</id>
		<title>GNU Linux/Workarounds</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Workarounds&amp;diff=52"/>
		<updated>2025-03-13T23:31:47Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Knowledge Base]]&lt;br /&gt;
A lot of distributions come fairly close to being perfect, but sometimes workarounds are required to improve the user experience. Please note that these are filed under distribution and driver specific sections, so may or may not be suitable for other combinations.&lt;br /&gt;
&lt;br /&gt;
== Networking ==&lt;br /&gt;
&lt;br /&gt;
=== WiFi Hotspot Issues ===&lt;br /&gt;
&lt;br /&gt;
==== Broken IP Configuration ====&lt;br /&gt;
In my case, after installing Docker on endeavourOS, I found that my hotspot could be connected to, but, the client was unable to obtain an IP address. I was using GNOME&#039;s settings applet, which is a wrapper for NetworkManager.&lt;br /&gt;
&lt;br /&gt;
Luckily, using iptables, based on hints provided by (https://wiki.archlinux.org/title/Internet_sharing#With_iptables)[https://wiki.archlinux.org/title/Internet_sharing#With_iptables], I could add a link level packet filter with NAT, using something similar to the these commands (with superuser privileges):&lt;br /&gt;
&lt;br /&gt;
 iptables -t nat -A POSTROUTING -o &amp;lt;ethernet interface name&amp;gt; -j MASQUERADE&lt;br /&gt;
 iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT&lt;br /&gt;
 iptables -A FORWARD -i &amp;lt;wifi adapter name&amp;gt; -o &amp;lt;ethernet interface name&amp;gt; -j ACCEPT&lt;br /&gt;
&lt;br /&gt;
You can find the network interface names with ifconfig.&lt;br /&gt;
&lt;br /&gt;
=== Wayland User Experience ===&lt;br /&gt;
==== Lag with NVIDIA GPU&#039;s ====&lt;br /&gt;
If you have an AMD graphics card, either integrated or dedicated, you will likely be accustomed to having a better user experience than those with NVIDIA graphics cards.&lt;br /&gt;
&lt;br /&gt;
Wayland works pretty well, but memory and other clock settings stay at too low of a frequency, causing lag. This is noticeable with the GNOME desktop shell. I use this code below to increase the minimum clock speeds on my dedicated GPU.&lt;br /&gt;
 sudo nvidia-smi -pm 1&lt;br /&gt;
 sudo nvidia-smi -lmc 1000,6000&lt;br /&gt;
 sudo nvidia-smi -lgc 1000,2000&lt;br /&gt;
The first command enables the persistence mode daemon, which keeps the kernel mode driver running (even when no other application is actively using it), the second locks the memory clock between 1000 and 6000 MHz, and the last, locks the graphics clock to be between 1000 and 2000 MHz. The command line arguments cannot be combined into one invocation, as nvidia-smi will not allow it.&lt;br /&gt;
&lt;br /&gt;
I&#039;ve found it useful to have a systemd service to do this automatically, when the system starts. I have written a file located here: &#039;&#039;&#039;/etc/systemd/system/nvidia-fix-clocks.service:&#039;&#039;&#039;&lt;br /&gt;
 [Unit]&lt;br /&gt;
 Description=Boost NVIDIA GPU memory and graphics clock speeds&lt;br /&gt;
 &lt;br /&gt;
 [Service]&lt;br /&gt;
 Type=oneshot&lt;br /&gt;
 ExecStart=/opt/ScriptFixes/nv_fix_clocks.sh&lt;br /&gt;
 &lt;br /&gt;
 [Install]&lt;br /&gt;
 WantedBy=multi-user.target&lt;br /&gt;
Don&#039;t forget to reload systemd&#039;s daemon with &#039;&#039;&#039;systemctl reload-daemon&#039;&#039;&#039;, and to enable the service with &#039;&#039;&#039;systemctl enable nvidia-fix-clocks.service&#039;&#039;&#039;. The changes will apply on the next reboot.&lt;br /&gt;
&lt;br /&gt;
==== OpenGL/X11 Application Not Running With a Dedicated NVIDIA GPU ====&lt;br /&gt;
I encountered this issue when running &#039;&#039;Freecad,&#039;&#039; which, in my case, could not use my dedicated GPU due to initialization issues with the OpenGL Extension for X11 (GLX). I use this code below, within a script, to ensure Freecad&#039;s rendering path goes a different way:&lt;br /&gt;
 Xwayland -decorate -geometry 1920x1080 :2 &amp;amp;&lt;br /&gt;
 QT_QPA_PLATFORM=xcb prime-run freecad -display :2&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Workarounds&amp;diff=51</id>
		<title>GNU Linux/Workarounds</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Workarounds&amp;diff=51"/>
		<updated>2025-02-25T08:09:51Z</updated>

		<summary type="html">&lt;p&gt;Root: /* Lag with NVIDIA GPU&amp;#039;s */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Knowledge Base]]&lt;br /&gt;
A lot of distributions come fairly close to being perfect, but sometimes workarounds are required to improve the user experience. Please note that these are filed under distribution and driver specific sections, so may or may not be suitable for other combinations.&lt;br /&gt;
&lt;br /&gt;
== EndeavourOS ==&lt;br /&gt;
&lt;br /&gt;
=== Wayland User Experience ===&lt;br /&gt;
&lt;br /&gt;
==== Lag with NVIDIA GPU&#039;s ====&lt;br /&gt;
If you have an AMD graphics card, either integrated or dedicated, you will likely be accustomed to having a better user experience than those with NVIDIA graphics cards.&lt;br /&gt;
&lt;br /&gt;
Wayland works pretty well, but memory and other clock settings stay at too low of a frequency, causing lag. This is noticeable with the GNOME desktop shell. I use this code below to increase the minimum clock speeds on my dedicated GPU.&lt;br /&gt;
 sudo nvidia-smi -pm 1&lt;br /&gt;
 sudo nvidia-smi -lmc 1000,6000&lt;br /&gt;
 sudo nvidia-smi -lgc 1000,2000&lt;br /&gt;
The first command enables the persistence mode daemon, which keeps the kernel mode driver running (even when no other application is actively using it), the second locks the memory clock between 1000 and 6000 MHz, and the last, locks the graphics clock to be between 1000 and 2000 MHz. The command line arguments cannot be combined into one invocation, as nvidia-smi will not allow it.&lt;br /&gt;
&lt;br /&gt;
I&#039;ve found it useful to have a systemd service to do this automatically, when the system starts. I have written a file located here: &#039;&#039;&#039;/etc/systemd/system/nvidia-fix-clocks.service:&#039;&#039;&#039;&lt;br /&gt;
 [Unit]&lt;br /&gt;
 Description=Boost NVIDIA GPU memory and graphics clock speeds&lt;br /&gt;
 &lt;br /&gt;
 [Service]&lt;br /&gt;
 Type=oneshot&lt;br /&gt;
 ExecStart=/opt/ScriptFixes/nv_fix_clocks.sh&lt;br /&gt;
 &lt;br /&gt;
 [Install]&lt;br /&gt;
 WantedBy=multi-user.target&lt;br /&gt;
Don&#039;t forget to reload systemd&#039;s daemon with &#039;&#039;&#039;systemctl reload-daemon&#039;&#039;&#039;, and to enable the service with &#039;&#039;&#039;systemctl enable nvidia-fix-clocks.service&#039;&#039;&#039;. The changes will apply on the next reboot.&lt;br /&gt;
&lt;br /&gt;
==== OpenGL/X11 Application Not Running With a Dedicated NVIDIA GPU ====&lt;br /&gt;
I encountered this issue when running &#039;&#039;Freecad,&#039;&#039; which, in my case, could not use my dedicated GPU due to initialization issues with the OpenGL Extension for X11 (GLX). I use this code below, within a script, to ensure Freecad&#039;s rendering path goes a different way:&lt;br /&gt;
 Xwayland -decorate -geometry 1920x1080 :2 &amp;amp;&lt;br /&gt;
 QT_QPA_PLATFORM=xcb prime-run freecad -display :2&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Useful_Commands&amp;diff=50</id>
		<title>GNU Linux/Useful Commands</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Useful_Commands&amp;diff=50"/>
		<updated>2025-02-10T00:03:00Z</updated>

		<summary type="html">&lt;p&gt;Root: /* Virtual Machines */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Knowledge Base|GNU Linux]]&lt;br /&gt;
&lt;br /&gt;
== File Conversion ==&lt;br /&gt;
&lt;br /&gt;
=== Batch Convert Man Pages into HTML files ===&lt;br /&gt;
Requires the &amp;lt;code&amp;gt;mandoc&amp;lt;/code&amp;gt; program to be installed.&lt;br /&gt;
 &amp;lt;code&amp;gt;mkdir html &amp;amp;&amp;amp; for x in .; do mandoc -Thtml -O man=./html/%N.%S.html,toc $x &amp;gt; html/$x.html; done&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Virtual Machines ==&lt;br /&gt;
I&#039;ve found this to be more useful than &amp;lt;code&amp;gt;guestmount&amp;lt;/code&amp;gt; (provided by the &amp;lt;code&amp;gt;libguestfs-tools&amp;lt;/code&amp;gt; package for Ubuntu), because it does not require superuser privileges to execute, and is easy to unmount afterwards. Based on the answer provided on Super User: &amp;lt;nowiki&amp;gt;https://superuser.com/a/1548983&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
 &amp;lt;code&amp;gt;mkdir -p ~/tmp/windows10-vm&lt;br /&gt;
 nbdfuse ~/tmp/windows10-vm [ qemu-nbd path_to_disk_image ] &amp;amp;&lt;br /&gt;
 fusermount -u ~/tmp/windows10-vm&amp;lt;/code&amp;gt;&lt;br /&gt;
An alternative is to let QEMU mount the virtual machine disk image with the NBD driver. Enable the nbd kernel module, mount the image, and then mount the partition with flags to make it accessible to other users without superuser privileges. &lt;br /&gt;
&lt;br /&gt;
With fdisk, you can identify the device file pertaining to the partition you want to mount (I&#039;ve used /dev/nbd0p1 for example). The dmask and fmask, are for the octal permission bits of directories and files.&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to run umount when finished.&lt;br /&gt;
 modprobe nbd&lt;br /&gt;
 qemu-nbd --connect=/dev/nbd0 &amp;lt;path to VM disk image&amp;gt;&lt;br /&gt;
 fdisk -l /dev/nbd0&lt;br /&gt;
 mount /dev/nbd0p1 /mnt/vhd1 -o dmask=000,fmask=000&lt;br /&gt;
 umount /mnt/vhd1&lt;br /&gt;
&lt;br /&gt;
== NVIDIA ==&lt;br /&gt;
To workaround a bug where the frame rate drops for Mutter and other applications, when they are viewed on an external monitor, boost the memory clock speed with this command below. The two values after lmc are the minimum and maximum memory clock speeds in MHz.&lt;br /&gt;
 sudo nvidia-smi -lmc 2000,6000&lt;br /&gt;
&lt;br /&gt;
== Making Changes to Windows Registry Hive Files ==&lt;br /&gt;
&#039;&#039;&#039;NB: It is recommended that you should make backup copies of any hive files you intend to edit, and store them on a separate partition.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The Windows registry consists of keys and values, belonging to hives. These hives are stored under &amp;lt;code&amp;gt;C:\Windows\system32\config&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
According to Microsoft&#039;s official documentation (https://learn.microsoft.com/en-us/windows/win32/sysinfo/registry-hives), these are the root keys and the hive file names which they correspond to:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Registry hive&lt;br /&gt;
!Supporting files&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_CURRENT_CONFIG&#039;&#039;&#039;&lt;br /&gt;
|System, System.alt, System.log, System.sav&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_CURRENT_USER&#039;&#039;&#039;&lt;br /&gt;
|Ntuser.dat, Ntuser.dat.log&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_LOCAL_MACHINE\SAM&#039;&#039;&#039;&lt;br /&gt;
|Sam, Sam.log, Sam.sav&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_LOCAL_MACHINE\Security&#039;&#039;&#039;&lt;br /&gt;
|Security, Security.log, Security.sav&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_LOCAL_MACHINE\Software&#039;&#039;&#039;&lt;br /&gt;
|Software, Software.log, Software.sav&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_LOCAL_MACHINE\System&#039;&#039;&#039;&lt;br /&gt;
|System, System.alt, System.log, System.sav&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_USERS\.DEFAULT&#039;&#039;&#039;&lt;br /&gt;
|Default, Default.log, Default.sav&lt;br /&gt;
|}I find it useful to browse through sub-keys and values with &amp;lt;code&amp;gt;hivexsh &amp;lt;path to hive&amp;gt;&amp;lt;/code&amp;gt; , then export a key from the hive file (using the file for  HKEY_LOCAL_MACHINE\Software for example): &lt;br /&gt;
 &amp;lt;code&amp;gt;hivexregedit --export ./SOFTWARE Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer &amp;gt; explorer-policies.reg&amp;lt;/code&amp;gt;&lt;br /&gt;
 &amp;lt;code&amp;gt;&lt;br /&gt;
 hivexregedit --merge ./SOFTWARE ./explorer-policies.reg&amp;lt;/code&amp;gt;&lt;br /&gt;
I&#039;ve left out the conversion of the exported registry file from Windows UTF-16 to UTF-8, and back again to UTF-16 before the merge, as I&#039;ve found through testing that this isn&#039;t needed (with hivex version 1.3.23).&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=Recipes/Oatmeal&amp;diff=49</id>
		<title>Recipes/Oatmeal</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=Recipes/Oatmeal&amp;diff=49"/>
		<updated>2025-02-03T05:45:15Z</updated>

		<summary type="html">&lt;p&gt;Root: Created page with &amp;quot;Baking  === Ingredients ===  * 1⁄2 cup plain rolled oats * 2 1⁄2 cups water * 1 teaspoon Turmeric * 2 tablespoons of Greek/plain yogurt * 2 tablespoons of protein powder * 1 banana, to season, sliced (optional)  === Method ===  # Add the oats to the pot, stir through the turmeric. # Add the water, and bring to the boil, making sure to continually stir vigorously, to prevent boiling over. # When reduced to a desired consistency (usually after 15 minu...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Food|Baking]]&lt;br /&gt;
&lt;br /&gt;
=== Ingredients ===&lt;br /&gt;
&lt;br /&gt;
* 1⁄2 cup plain rolled oats&lt;br /&gt;
* 2 1⁄2 cups water&lt;br /&gt;
* 1 teaspoon Turmeric&lt;br /&gt;
* 2 tablespoons of Greek/plain yogurt&lt;br /&gt;
* 2 tablespoons of protein powder&lt;br /&gt;
* 1 banana, to season, sliced (optional)&lt;br /&gt;
&lt;br /&gt;
=== Method ===&lt;br /&gt;
&lt;br /&gt;
# Add the oats to the pot, stir through the turmeric.&lt;br /&gt;
# Add the water, and bring to the boil, making sure to continually stir vigorously, to prevent boiling over.&lt;br /&gt;
# When reduced to a desired consistency (usually after 15 minutes), turn off the heat.&lt;br /&gt;
# Stir through the protein powder.&lt;br /&gt;
# Serve with the sliced banana, and stir through with the yogurt.&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=Recipes/Hemp_Powder_Biscuits&amp;diff=48</id>
		<title>Recipes/Hemp Powder Biscuits</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=Recipes/Hemp_Powder_Biscuits&amp;diff=48"/>
		<updated>2025-02-03T05:37:08Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Food|Baking]]&lt;br /&gt;
This recipe is based on one titled &amp;quot;Coconut Biscuits&amp;quot;, found in an old cookbook. Makes 10.&lt;br /&gt;
&lt;br /&gt;
=== Ingredients ===&lt;br /&gt;
&lt;br /&gt;
* 60g unsalted pure butter&lt;br /&gt;
* 1 egg&lt;br /&gt;
* 1⁄4 cup brown sugar&lt;br /&gt;
* 1⁄2 cup wheat flour&lt;br /&gt;
* 1⁄2 cup hemp seed powder&lt;br /&gt;
* 1 teaspoon baking powder&lt;br /&gt;
&lt;br /&gt;
=== Method ===&lt;br /&gt;
&lt;br /&gt;
# Cream butter and sugar. &lt;br /&gt;
# Add egg and beat. &lt;br /&gt;
# Mix together the baking powder, wheat flour and the hemp powder, and sieve into the bowl. &lt;br /&gt;
# Mix well.&lt;br /&gt;
# Form into evenly sized balls, and press them with a fork.&lt;br /&gt;
# Bake in the oven at 180 degrees for approximately 20 minutes.&lt;br /&gt;
# Leave to cool for a while before serving.&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=Recipes/Hemp_Powder_Biscuits&amp;diff=47</id>
		<title>Recipes/Hemp Powder Biscuits</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=Recipes/Hemp_Powder_Biscuits&amp;diff=47"/>
		<updated>2025-02-03T05:36:21Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Food|Baking]]&lt;br /&gt;
This recipe is based on one found in an old cookbook, titled &amp;quot;Coconut Biscuits&amp;quot;. Makes 10.&lt;br /&gt;
&lt;br /&gt;
=== Ingredients ===&lt;br /&gt;
&lt;br /&gt;
* 60g unsalted pure butter&lt;br /&gt;
* 1 egg&lt;br /&gt;
* 1⁄4 cup brown sugar&lt;br /&gt;
* 1⁄2 cup wheat flour&lt;br /&gt;
* 1⁄2 cup hemp seed powder&lt;br /&gt;
* 1 teaspoon baking powder&lt;br /&gt;
&lt;br /&gt;
=== Method ===&lt;br /&gt;
&lt;br /&gt;
# Cream butter and sugar. &lt;br /&gt;
# Add egg and beat. &lt;br /&gt;
# Mix together the baking powder, wheat flour and the hemp powder, and sieve into the bowl. &lt;br /&gt;
# Mix well.&lt;br /&gt;
# Form into evenly sized balls, and press them with a fork.&lt;br /&gt;
# Bake in the oven at 180 degrees for approximately 20 minutes.&lt;br /&gt;
# Leave to cool for a while before serving.&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=Main_Page&amp;diff=46</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=Main_Page&amp;diff=46"/>
		<updated>2025-02-03T05:23:14Z</updated>

		<summary type="html">&lt;p&gt;Root: /* Directory */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://www.bgcottrell.com &amp;lt; Go back to bgcottrell.com]&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;Strong&amp;gt;Welcome&amp;lt;/Strong&amp;gt; ==&lt;br /&gt;
This is a place to store gathered ideas, providing a knowledge base, and more, sharing pieces of information that I&#039;ve found useful.&lt;br /&gt;
&lt;br /&gt;
=== Directory ===&lt;br /&gt;
&amp;lt;categorytree mode=&amp;quot;all&amp;quot; depth=&amp;quot;6&amp;quot;&amp;gt;Knowledge Base&amp;lt;/categorytree&amp;gt;&lt;br /&gt;
&amp;lt;categorytree mode=&amp;quot;all&amp;quot; depth=&amp;quot;6&amp;quot;&amp;gt;Food&amp;lt;/categorytree&amp;gt;&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=Main_Page&amp;diff=45</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=Main_Page&amp;diff=45"/>
		<updated>2025-02-03T05:18:11Z</updated>

		<summary type="html">&lt;p&gt;Root: /* Directory */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://www.bgcottrell.com &amp;lt; Go back to bgcottrell.com]&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;Strong&amp;gt;Welcome&amp;lt;/Strong&amp;gt; ==&lt;br /&gt;
This is a place to store gathered ideas, providing a knowledge base, and more, sharing pieces of information that I&#039;ve found useful.&lt;br /&gt;
&lt;br /&gt;
=== Directory ===&lt;br /&gt;
&amp;lt;categorytree mode=&amp;quot;all&amp;quot; depth=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/categorytree&amp;gt;&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=Category:Food&amp;diff=44</id>
		<title>Category:Food</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=Category:Food&amp;diff=44"/>
		<updated>2025-02-03T05:16:25Z</updated>

		<summary type="html">&lt;p&gt;Root: Created page with &amp;quot;== Food ==&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Food ==&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=Main_Page&amp;diff=43</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=Main_Page&amp;diff=43"/>
		<updated>2025-02-03T04:22:44Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://www.bgcottrell.com &amp;lt; Go back to bgcottrell.com]&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;Strong&amp;gt;Welcome&amp;lt;/Strong&amp;gt; ==&lt;br /&gt;
This is a place to store gathered ideas, providing a knowledge base, and more, sharing pieces of information that I&#039;ve found useful.&lt;br /&gt;
&lt;br /&gt;
=== Directory ===&lt;br /&gt;
&amp;lt;categorytree mode=&amp;quot;all&amp;quot; depth=&amp;quot;6&amp;quot;&amp;gt;Knowledge Base&amp;lt;/categorytree&amp;gt;&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=Recipes/Hemp_Powder_Biscuits&amp;diff=42</id>
		<title>Recipes/Hemp Powder Biscuits</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=Recipes/Hemp_Powder_Biscuits&amp;diff=42"/>
		<updated>2025-02-03T04:22:21Z</updated>

		<summary type="html">&lt;p&gt;Root: Created page with &amp;quot;Baking Watch this space&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Food|Baking]]&lt;br /&gt;
Watch this space&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Workarounds&amp;diff=41</id>
		<title>GNU Linux/Workarounds</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Workarounds&amp;diff=41"/>
		<updated>2025-01-29T09:40:33Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Knowledge Base]]&lt;br /&gt;
A lot of distributions come fairly close to being perfect, but sometimes workarounds are required to improve the user experience. Please note that these are filed under distribution and driver specific sections, so may or may not be suitable for other combinations.&lt;br /&gt;
&lt;br /&gt;
== EndeavourOS ==&lt;br /&gt;
&lt;br /&gt;
=== Wayland User Experience ===&lt;br /&gt;
&lt;br /&gt;
==== Lag with NVIDIA GPU&#039;s ====&lt;br /&gt;
If you have an AMD graphics card, either integrated or dedicated, you will likely be accustomed to having a better user experience than those with NVIDIA graphics cards.&lt;br /&gt;
&lt;br /&gt;
Wayland works pretty well, but memory and other clock settings stay at too low of a frequency, causing lag. This is noticeable with the GNOME desktop shell. I use this code below to increase the minimum clock speeds on my dedicated GPU.&lt;br /&gt;
 sudo nvidia-smi -pm 1&lt;br /&gt;
 sudo nvidia-smi -lmc 1000,6000&lt;br /&gt;
 sudo nvidia-smi -lgc 1000,2000&lt;br /&gt;
The first command enables the persistence mode daemon, which keeps the kernel mode driver running (even when no other application is actively using it), the second locks the memory clock between 1000 and 6000 MHz, and the last, locks the graphics clock to be between 1000 and 2000 MHz.&lt;br /&gt;
&lt;br /&gt;
==== OpenGL/X11 Application Not Running With a Dedicated NVIDIA GPU ====&lt;br /&gt;
I encountered this issue when running &#039;&#039;Freecad,&#039;&#039; which, in my case, could not use my dedicated GPU due to initialization issues with the OpenGL Extension for X11 (GLX). I use this code below, within a script, to ensure Freecad&#039;s rendering path goes a different way:&lt;br /&gt;
 Xwayland -decorate -geometry 1920x1080 :2 &amp;amp;&lt;br /&gt;
 QT_QPA_PLATFORM=xcb prime-run freecad -display :2&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Useful_Commands&amp;diff=40</id>
		<title>GNU Linux/Useful Commands</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Useful_Commands&amp;diff=40"/>
		<updated>2025-01-29T09:37:08Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Knowledge Base|GNU Linux]]&lt;br /&gt;
&lt;br /&gt;
== File Conversion ==&lt;br /&gt;
&lt;br /&gt;
=== Batch Convert Man Pages into HTML files ===&lt;br /&gt;
Requires the &amp;lt;code&amp;gt;mandoc&amp;lt;/code&amp;gt; program to be installed.&lt;br /&gt;
 &amp;lt;code&amp;gt;mkdir html &amp;amp;&amp;amp; for x in .; do mandoc -Thtml -O man=./html/%N.%S.html,toc $x &amp;gt; html/$x.html; done&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Virtual Machines ==&lt;br /&gt;
I&#039;ve found this to be more useful than &amp;lt;code&amp;gt;guestmount&amp;lt;/code&amp;gt; (provided by the &amp;lt;code&amp;gt;libguestfs-tools&amp;lt;/code&amp;gt; package for Ubuntu), because it does not require superuser privileges to execute, and is easy to unmount afterwards. Based on the answer provided on Super User: &amp;lt;nowiki&amp;gt;https://superuser.com/a/1548983&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
 &amp;lt;code&amp;gt;mkdir -p ~/tmp/windows10-vm&lt;br /&gt;
 nbdfuse ~/tmp/windows10-vm [ qemu-nbd path_to_disk_image ] &amp;amp;&lt;br /&gt;
 fusermount -u ~/tmp/windows10-vm&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== NVIDIA ==&lt;br /&gt;
To workaround a bug where the frame rate drops for Mutter and other applications, when they are viewed on an external monitor, boost the memory clock speed with this command below. The two values after lmc are the minimum and maximum memory clock speeds in MHz.&lt;br /&gt;
 sudo nvidia-smi -lmc 2000,6000&lt;br /&gt;
&lt;br /&gt;
== Making Changes to Windows Registry Hive Files ==&lt;br /&gt;
&#039;&#039;&#039;NB: It is recommended that you should make backup copies of any hive files you intend to edit, and store them on a separate partition.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The Windows registry consists of keys and values, belonging to hives. These hives are stored under &amp;lt;code&amp;gt;C:\Windows\system32\config&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
According to Microsoft&#039;s official documentation (https://learn.microsoft.com/en-us/windows/win32/sysinfo/registry-hives), these are the root keys and the hive file names which they correspond to:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Registry hive&lt;br /&gt;
!Supporting files&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_CURRENT_CONFIG&#039;&#039;&#039;&lt;br /&gt;
|System, System.alt, System.log, System.sav&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_CURRENT_USER&#039;&#039;&#039;&lt;br /&gt;
|Ntuser.dat, Ntuser.dat.log&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_LOCAL_MACHINE\SAM&#039;&#039;&#039;&lt;br /&gt;
|Sam, Sam.log, Sam.sav&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_LOCAL_MACHINE\Security&#039;&#039;&#039;&lt;br /&gt;
|Security, Security.log, Security.sav&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_LOCAL_MACHINE\Software&#039;&#039;&#039;&lt;br /&gt;
|Software, Software.log, Software.sav&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_LOCAL_MACHINE\System&#039;&#039;&#039;&lt;br /&gt;
|System, System.alt, System.log, System.sav&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HKEY_USERS\.DEFAULT&#039;&#039;&#039;&lt;br /&gt;
|Default, Default.log, Default.sav&lt;br /&gt;
|}I find it useful to browse through sub-keys and values with &amp;lt;code&amp;gt;hivexsh &amp;lt;path to hive&amp;gt;&amp;lt;/code&amp;gt; , then export a key from the hive file (using the file for  HKEY_LOCAL_MACHINE\Software for example): &lt;br /&gt;
 &amp;lt;code&amp;gt;hivexregedit --export ./SOFTWARE Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer &amp;gt; explorer-policies.reg&amp;lt;/code&amp;gt;&lt;br /&gt;
 &amp;lt;code&amp;gt;&lt;br /&gt;
 hivexregedit --merge ./SOFTWARE ./explorer-policies.reg&amp;lt;/code&amp;gt;&lt;br /&gt;
I&#039;ve left out the conversion of the exported registry file from Windows UTF-16 to UTF-8, and back again to UTF-16 before the merge, as I&#039;ve found through testing that this isn&#039;t needed (with hivex version 1.3.23).&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=Qt_Framework&amp;diff=39</id>
		<title>Qt Framework</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=Qt_Framework&amp;diff=39"/>
		<updated>2025-01-07T01:32:47Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Knowledge Base]]&lt;br /&gt;
== Tool Workarounds ==&lt;br /&gt;
&lt;br /&gt;
=== Creator ===&lt;br /&gt;
The Creator IDE still does not implement a style plugin, which, makes improving the contrast of widgets to be more difficult. The scrollbars still could have greater contrast. I&#039;ve used this stylesheet file, shown below, and passed it to the &amp;quot;-stylesheet&amp;quot; option to creator when launching it:&lt;br /&gt;
&lt;br /&gt;
 /* Define a style for the vertical scrollbar */&lt;br /&gt;
 QScrollBar:vertical {&lt;br /&gt;
     background: #3f3f3f; /* Set the background color */&lt;br /&gt;
 }&lt;br /&gt;
 /* Define a style for the horizontal scrollbar */&lt;br /&gt;
 QScrollBar:horizontal {&lt;br /&gt;
     background: #3f3f3f; /* Set the background color */&lt;br /&gt;
     &lt;br /&gt;
 }&lt;br /&gt;
 /* Define a style for the handle (the draggable part) of the scrollbar */&lt;br /&gt;
 QScrollBar::handle:vertical,&lt;br /&gt;
 QScrollBar::handle:horizontal {&lt;br /&gt;
     background: #999999; /* Set the color of the handle */&lt;br /&gt;
     min-height: 20px; /* Set the minimum height of the handle */&lt;br /&gt;
 }&lt;br /&gt;
 QLabel::Link, QLabel::LinkVisited {&lt;br /&gt;
     color: &amp;quot;white&amp;quot;;&lt;br /&gt;
 }&lt;br /&gt;
 /* Define a style for the page-up and page-down buttons */&lt;br /&gt;
 QScrollBar::add-line:vertical,&lt;br /&gt;
 QScrollBar::sub-line:vertical,&lt;br /&gt;
 QScrollBar::add-line:horizontal,&lt;br /&gt;
 QScrollBar::sub-line:horizontal {&lt;br /&gt;
     background: #CCCCCC; /* Set the background color */&lt;br /&gt;
 }&lt;br /&gt;
 /* Define a style for the page-up and page-down buttons when hovered */&lt;br /&gt;
 QScrollBar::add-line:vertical:hover,&lt;br /&gt;
 QScrollBar::sub-line:vertical:hover,&lt;br /&gt;
 QScrollBar::add-line:horizontal:hover,&lt;br /&gt;
 QScrollBar::sub-line:horizontal:hover {&lt;br /&gt;
     background: #999999; /* Set the background color when hovered */&lt;br /&gt;
 }&lt;br /&gt;
 /* Define a style for the arrows of the page-up and page-down buttons */&lt;br /&gt;
 QScrollBar::up-arrow:vertical,&lt;br /&gt;
 QScrollBar::down-arrow:vertical,&lt;br /&gt;
 QScrollBar::up-arrow:horizontal,&lt;br /&gt;
 QScrollBar::down-arrow:horizontal {&lt;br /&gt;
     background: #999999; /* Set the color of the arrow */&lt;br /&gt;
 }&lt;br /&gt;
 /* Define a style for the arrows of the page-up and page-down buttons when hovered */&lt;br /&gt;
 QScrollBar::up-arrow:vertical:hover,&lt;br /&gt;
 QScrollBar::down-arrow:vertical:hover,&lt;br /&gt;
 QScrollBar::up-arrow:horizontal:hover,&lt;br /&gt;
 QScrollBar::down-arrow:horizontal:hover {&lt;br /&gt;
     background: #CCCCCC; /* Set the background color of the arrow when hovered */&lt;br /&gt;
 }&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=Qt_Framework&amp;diff=38</id>
		<title>Qt Framework</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=Qt_Framework&amp;diff=38"/>
		<updated>2025-01-07T01:32:40Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[Category:Knowledge Base]&lt;br /&gt;
== Tool Workarounds ==&lt;br /&gt;
&lt;br /&gt;
=== Creator ===&lt;br /&gt;
The Creator IDE still does not implement a style plugin, which, makes improving the contrast of widgets to be more difficult. The scrollbars still could have greater contrast. I&#039;ve used this stylesheet file, shown below, and passed it to the &amp;quot;-stylesheet&amp;quot; option to creator when launching it:&lt;br /&gt;
&lt;br /&gt;
 /* Define a style for the vertical scrollbar */&lt;br /&gt;
 QScrollBar:vertical {&lt;br /&gt;
     background: #3f3f3f; /* Set the background color */&lt;br /&gt;
 }&lt;br /&gt;
 /* Define a style for the horizontal scrollbar */&lt;br /&gt;
 QScrollBar:horizontal {&lt;br /&gt;
     background: #3f3f3f; /* Set the background color */&lt;br /&gt;
     &lt;br /&gt;
 }&lt;br /&gt;
 /* Define a style for the handle (the draggable part) of the scrollbar */&lt;br /&gt;
 QScrollBar::handle:vertical,&lt;br /&gt;
 QScrollBar::handle:horizontal {&lt;br /&gt;
     background: #999999; /* Set the color of the handle */&lt;br /&gt;
     min-height: 20px; /* Set the minimum height of the handle */&lt;br /&gt;
 }&lt;br /&gt;
 QLabel::Link, QLabel::LinkVisited {&lt;br /&gt;
     color: &amp;quot;white&amp;quot;;&lt;br /&gt;
 }&lt;br /&gt;
 /* Define a style for the page-up and page-down buttons */&lt;br /&gt;
 QScrollBar::add-line:vertical,&lt;br /&gt;
 QScrollBar::sub-line:vertical,&lt;br /&gt;
 QScrollBar::add-line:horizontal,&lt;br /&gt;
 QScrollBar::sub-line:horizontal {&lt;br /&gt;
     background: #CCCCCC; /* Set the background color */&lt;br /&gt;
 }&lt;br /&gt;
 /* Define a style for the page-up and page-down buttons when hovered */&lt;br /&gt;
 QScrollBar::add-line:vertical:hover,&lt;br /&gt;
 QScrollBar::sub-line:vertical:hover,&lt;br /&gt;
 QScrollBar::add-line:horizontal:hover,&lt;br /&gt;
 QScrollBar::sub-line:horizontal:hover {&lt;br /&gt;
     background: #999999; /* Set the background color when hovered */&lt;br /&gt;
 }&lt;br /&gt;
 /* Define a style for the arrows of the page-up and page-down buttons */&lt;br /&gt;
 QScrollBar::up-arrow:vertical,&lt;br /&gt;
 QScrollBar::down-arrow:vertical,&lt;br /&gt;
 QScrollBar::up-arrow:horizontal,&lt;br /&gt;
 QScrollBar::down-arrow:horizontal {&lt;br /&gt;
     background: #999999; /* Set the color of the arrow */&lt;br /&gt;
 }&lt;br /&gt;
 /* Define a style for the arrows of the page-up and page-down buttons when hovered */&lt;br /&gt;
 QScrollBar::up-arrow:vertical:hover,&lt;br /&gt;
 QScrollBar::down-arrow:vertical:hover,&lt;br /&gt;
 QScrollBar::up-arrow:horizontal:hover,&lt;br /&gt;
 QScrollBar::down-arrow:horizontal:hover {&lt;br /&gt;
     background: #CCCCCC; /* Set the background color of the arrow when hovered */&lt;br /&gt;
 }&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=Qt_Framework&amp;diff=37</id>
		<title>Qt Framework</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=Qt_Framework&amp;diff=37"/>
		<updated>2025-01-07T01:32:21Z</updated>

		<summary type="html">&lt;p&gt;Root: Created page with &amp;quot;== Tool Workarounds ==  === Creator === The Creator IDE still does not implement a style plugin, which, makes improving the contrast of widgets to be more difficult. The scrollbars still could have greater contrast. I&amp;#039;ve used this stylesheet file, shown below, and passed it to the &amp;quot;-stylesheet&amp;quot; option to creator when launching it:   /* Define a style for the vertical scrollbar */  QScrollBar:vertical {      background: #3f3f3f; /* Set the background color */  }  /* Defin...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Tool Workarounds ==&lt;br /&gt;
&lt;br /&gt;
=== Creator ===&lt;br /&gt;
The Creator IDE still does not implement a style plugin, which, makes improving the contrast of widgets to be more difficult. The scrollbars still could have greater contrast. I&#039;ve used this stylesheet file, shown below, and passed it to the &amp;quot;-stylesheet&amp;quot; option to creator when launching it:&lt;br /&gt;
&lt;br /&gt;
 /* Define a style for the vertical scrollbar */&lt;br /&gt;
 QScrollBar:vertical {&lt;br /&gt;
     background: #3f3f3f; /* Set the background color */&lt;br /&gt;
 }&lt;br /&gt;
 /* Define a style for the horizontal scrollbar */&lt;br /&gt;
 QScrollBar:horizontal {&lt;br /&gt;
     background: #3f3f3f; /* Set the background color */&lt;br /&gt;
     &lt;br /&gt;
 }&lt;br /&gt;
 /* Define a style for the handle (the draggable part) of the scrollbar */&lt;br /&gt;
 QScrollBar::handle:vertical,&lt;br /&gt;
 QScrollBar::handle:horizontal {&lt;br /&gt;
     background: #999999; /* Set the color of the handle */&lt;br /&gt;
     min-height: 20px; /* Set the minimum height of the handle */&lt;br /&gt;
 }&lt;br /&gt;
 QLabel::Link, QLabel::LinkVisited {&lt;br /&gt;
     color: &amp;quot;white&amp;quot;;&lt;br /&gt;
 }&lt;br /&gt;
 /* Define a style for the page-up and page-down buttons */&lt;br /&gt;
 QScrollBar::add-line:vertical,&lt;br /&gt;
 QScrollBar::sub-line:vertical,&lt;br /&gt;
 QScrollBar::add-line:horizontal,&lt;br /&gt;
 QScrollBar::sub-line:horizontal {&lt;br /&gt;
     background: #CCCCCC; /* Set the background color */&lt;br /&gt;
 }&lt;br /&gt;
 /* Define a style for the page-up and page-down buttons when hovered */&lt;br /&gt;
 QScrollBar::add-line:vertical:hover,&lt;br /&gt;
 QScrollBar::sub-line:vertical:hover,&lt;br /&gt;
 QScrollBar::add-line:horizontal:hover,&lt;br /&gt;
 QScrollBar::sub-line:horizontal:hover {&lt;br /&gt;
     background: #999999; /* Set the background color when hovered */&lt;br /&gt;
 }&lt;br /&gt;
 /* Define a style for the arrows of the page-up and page-down buttons */&lt;br /&gt;
 QScrollBar::up-arrow:vertical,&lt;br /&gt;
 QScrollBar::down-arrow:vertical,&lt;br /&gt;
 QScrollBar::up-arrow:horizontal,&lt;br /&gt;
 QScrollBar::down-arrow:horizontal {&lt;br /&gt;
     background: #999999; /* Set the color of the arrow */&lt;br /&gt;
 }&lt;br /&gt;
 /* Define a style for the arrows of the page-up and page-down buttons when hovered */&lt;br /&gt;
 QScrollBar::up-arrow:vertical:hover,&lt;br /&gt;
 QScrollBar::down-arrow:vertical:hover,&lt;br /&gt;
 QScrollBar::up-arrow:horizontal:hover,&lt;br /&gt;
 QScrollBar::down-arrow:horizontal:hover {&lt;br /&gt;
     background: #CCCCCC; /* Set the background color of the arrow when hovered */&lt;br /&gt;
 }&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=Main_Page&amp;diff=36</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=Main_Page&amp;diff=36"/>
		<updated>2025-01-07T01:23:59Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://www.bgcottrell.com &amp;lt; Go back to bgcottrell.com]&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;Strong&amp;gt;Welcome&amp;lt;/Strong&amp;gt; ==&lt;br /&gt;
This is a place to store gathered ideas, providing a knowledge base, and more, sharing pieces of information that I&#039;ve found useful.&lt;br /&gt;
&lt;br /&gt;
=== Directory ===&lt;br /&gt;
&amp;lt;categorytree mode=&amp;quot;all&amp;quot; depth=&amp;quot;5&amp;quot;&amp;gt;Knowledge Base&amp;lt;/categorytree&amp;gt;&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Workarounds&amp;diff=35</id>
		<title>GNU Linux/Workarounds</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Workarounds&amp;diff=35"/>
		<updated>2025-01-07T01:23:23Z</updated>

		<summary type="html">&lt;p&gt;Root: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Knowledge Base]]&lt;br /&gt;
A lot of distributions come fairly close to being perfect, but sometimes workarounds are required to improve the user experience. Please note that these are filed under distribution and driver specific sections, so may or may not be suitable for other combinations.&lt;br /&gt;
&lt;br /&gt;
== EndeavourOS ==&lt;br /&gt;
&lt;br /&gt;
=== Wayland User Experience ===&lt;br /&gt;
&lt;br /&gt;
==== Lag with NVIDIA GPU&#039;s ====&lt;br /&gt;
If you have an AMD graphics card, either integrated or dedicated, you will likely be accustomed to having a better user experience than those with NVIDIA graphics cards.&lt;br /&gt;
&lt;br /&gt;
Wayland works pretty well, but memory and other clock settings stay at too low of a frequency, causing lag. This is noticeable with the GNOME desktop shell. I use this code below to increase the minimum clock speeds on my dedicated GPU.&lt;br /&gt;
 sudo nvidia-smi -pm 1&lt;br /&gt;
 sudo nvidia-smi -lmc 1000,6000&lt;br /&gt;
 sudo nvidia-smi -lgc 1000,2000&lt;br /&gt;
The first command enables the persistence mode daemon, which keeps the kernel mode driver running (even when no other application is actively using it), the second locks the memory clock between 1000 and 6000 MHz, and the last, locks the graphics clock to be between 1000 and 2000 MHz.&lt;br /&gt;
&lt;br /&gt;
==== GLX Application not Running on NVIDIA GPU ====&lt;br /&gt;
I encountered this issue when running &#039;&#039;Freecad,&#039;&#039; which, in my case, could not use my dedicated GPU due to initialization issues with a GLX component (OpenGL Extensions for X11). I use this code below, within a script, to ensure Freecad&#039;s rendering path goes a different way:&lt;br /&gt;
 Xwayland -decorate -geometry 1920x1080 :2 &amp;amp;&lt;br /&gt;
 QT_QPA_PLATFORM=xcb prime-run freecad -display :2&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=GNU_Linux/&amp;diff=34</id>
		<title>GNU Linux/</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=GNU_Linux/&amp;diff=34"/>
		<updated>2025-01-07T01:19:32Z</updated>

		<summary type="html">&lt;p&gt;Root: Created page with &amp;quot; __FORCETOC__&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
__FORCETOC__&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
	<entry>
		<id>http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Workarounds&amp;diff=33</id>
		<title>GNU Linux/Workarounds</title>
		<link rel="alternate" type="text/html" href="http://wiki.bgcottrell.com/index.php?title=GNU_Linux/Workarounds&amp;diff=33"/>
		<updated>2025-01-07T01:18:17Z</updated>

		<summary type="html">&lt;p&gt;Root: Created page with &amp;quot;A lot of distributions come fairly close to being perfect, but sometimes workarounds are required to improve the user experience. Please note that these are filed under distribution and driver specific sections, so may or may not be suitable for other combinations.  == EndeavourOS ==  === Wayland User Experience ===  ==== Lag with NVIDIA GPU&amp;#039;s ==== If you have an AMD graphics card, either integrated or dedicated, you will likely be accustomed to having a better user expe...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A lot of distributions come fairly close to being perfect, but sometimes workarounds are required to improve the user experience. Please note that these are filed under distribution and driver specific sections, so may or may not be suitable for other combinations.&lt;br /&gt;
&lt;br /&gt;
== EndeavourOS ==&lt;br /&gt;
&lt;br /&gt;
=== Wayland User Experience ===&lt;br /&gt;
&lt;br /&gt;
==== Lag with NVIDIA GPU&#039;s ====&lt;br /&gt;
If you have an AMD graphics card, either integrated or dedicated, you will likely be accustomed to having a better user experience than those with NVIDIA graphics cards.&lt;br /&gt;
&lt;br /&gt;
Wayland works pretty well, but memory and other clock settings stay at too low of a frequency, causing lag. This is noticeable with the GNOME desktop shell. I use this code below to increase the minimum clock speeds on my dedicated GPU.&lt;br /&gt;
 sudo nvidia-smi -pm 1&lt;br /&gt;
 sudo nvidia-smi -lmc 1000,6000&lt;br /&gt;
 sudo nvidia-smi -lgc 1000,2000&lt;br /&gt;
The first command enables the persistence mode daemon, which keeps the kernel mode driver running (even when no other application is actively using it), the second locks the memory clock between 1000 and 6000 MHz, and the last, locks the graphics clock to be between 1000 and 2000 MHz.&lt;br /&gt;
&lt;br /&gt;
==== GLX Application not Running on NVIDIA GPU ====&lt;br /&gt;
I encountered this issue when running &#039;&#039;Freecad,&#039;&#039; which, in my case, could not use my dedicated GPU due to initialization issues with a GLX component (OpenGL Extensions for X11). I use this code below, within a script, to ensure Freecad&#039;s rendering path goes a different way:&lt;br /&gt;
 Xwayland -decorate -geometry 1920x1080 :2 &amp;amp;&lt;br /&gt;
 QT_QPA_PLATFORM=xcb prime-run freecad -display :2&lt;/div&gt;</summary>
		<author><name>Root</name></author>
	</entry>
</feed>