Skip to content

Commit 97f1e4e

Browse files
committed
main
1 parent e183560 commit 97f1e4e

File tree

5 files changed

+270
-4
lines changed

5 files changed

+270
-4
lines changed

docs/document/Articles/docs/ADB Cheat Sheet.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ adb sideload /path/to/rom.zip
3232

3333
## ABI
3434

35-
```ps1
35+
```sh
3636
adb shell getprop ro.vendor.product.cpu.abilist64
3737
adb shell getprop ro.vendor.product.cpu.abilist # all abi
3838
```
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
# Understanding Bit Operation
2+
3+
## Bit Shifting
4+
5+
### Left & Right Shifting
6+
7+
Left shifting moves the whole bit sequence with specific count to left, `0` will fill up the tail and the leading bits are just discarded.
8+
9+
```cs
10+
11+
uint before = 0b_1001_0000_0000_0000_0000_0000_0000_1001;
12+
uint after = before << 4;
13+
Console.WriteLine($"{nameof(before),6}: {before,32:B32}");
14+
Console.WriteLine($"{nameof(after),6}: {after:B32}");
15+
16+
// before: 10010000000000000000000000001001
17+
// ^^^^ ^^^^
18+
// discarded move left
19+
20+
// after: 00000000000000000000000010010000
21+
// ^^^^
22+
```
23+
24+
Right shifting does it reversely.
25+
The only difference is, when shifting on *signed* integers, bits would be filled with the sign bit value(`0` for positive, `1` for negative)
26+
27+
```cs
28+
sbyte before = sbyte.MinValue;
29+
sbyte after = (sbyte)(before >> 4);
30+
Console.WriteLine($"{nameof(before),6}: {before:B8}");
31+
Console.WriteLine($"{nameof(after),6}: {after:B8}");
32+
33+
```
34+
35+
> [!NOTE]
36+
> Left & Right Shifting supports only `int`, `uint`, `long`, `ulong`. If you perform shifting on other integer types, the leftoperand is converted as `int`
37+
38+
> [!NOTE]
39+
> If shift count exceeds the bit width or is even negative, the count is determined by
40+
> - if leftoperand is `int` or `uint`: `count = count & 0b_1_1111`
41+
> - if leftoperand is `long` or `ulong`: `count = count & 0b_11_1111`
42+
43+
> [!NOTE]
44+
> Left shifting might discard sign of the number when it's signed
45+
>```cs
46+
>int foo = -0b_0001_0001_0001_0001_0001_0001_0001_0001_01;
47+
>Console.WriteLine(foo.ToString("B32"));
48+
>Console.WriteLine((foo << 1).ToString("B32"));
49+
>Console.WriteLine(int.IsPositive(foo << 1));
50+
51+
>// 10111011101110111011101110111011
52+
>// 01110111011101110111011101110110
53+
>// True
54+
>```
55+
56+
### Unsigned Right Shifting
57+
58+
> [!NOTE]
59+
> `>>>` was supported since C# 11
60+
61+
If you want to make sure that the empty bits are filled with `0` instead of value of the sign when working with the signed integers, use `>>>`!
62+
63+
```cs
64+
int before = int.MinValue;
65+
int after = before >> 2;
66+
int afterUnsigned = before >>> 2; // [!code highlight]
67+
Console.WriteLine($"{nameof(before),-20}: {before:B32}");
68+
Console.WriteLine($"{nameof(after),-20}: {after:B32}");
69+
Console.WriteLine($"{nameof(afterUnsigned),-20}: {afterUnsigned:B32}");
70+
71+
// before : 10000000000000000000000000000000
72+
// after : 11100000000000000000000000000000
73+
// afterUnsigned : 00100000000000000000000000000000 // [!code highlight]
74+
```
75+
76+
> [!NOTE]
77+
> Before `>>>` was added, you had to perform casting to achieve the same
78+
>```cs
79+
>int afterUnsigned = unchecked((int)((uint)before >> 2));
80+
>```
81+
82+
## Bitwise NOT
83+
84+
Reverse value of each bit
85+
86+
```cs
87+
uint before = 0b_0100010;
88+
uint after = ~before;
89+
Console.WriteLine($"{nameof(before),6}: {before,32:B32}");
90+
Console.WriteLine($"{nameof(after),6}: {after:B}");
91+
// before: 00000000000000000000000000100010
92+
// after: 11111111111111111111111111011101
93+
```
94+
95+
## Bitwise OR & AND & XOR
96+
97+
- bitwise OR `|`: returns `1` for each bit as long as one of the two is `1`, else `0`
98+
- bitwise AND `&`: returns `1` for each bit as long as all of the two is `1`, else `0`
99+
- bitwise XOR `^`: returns `1` if the two bits are different, `0` when identical
100+
101+
102+
## Bitwise on Enum
103+
104+
Enum can be flags when the type is marked with `FlagsAttribute` and ordinary enum members are powers of 2(members represent the `All` or `None` are exceptional)
105+
106+
```cs
107+
[Flags]
108+
enum Foo
109+
{
110+
None = 0b0000,
111+
Bar = 0b0001,
112+
Baz = 0b0010,
113+
Qux = 0b0100,
114+
Goo = 0b1000,
115+
All = 0b1111
116+
}
117+
// powers can be easily done by left shifting
118+
[Flags]
119+
enum Foo
120+
{
121+
None = 0,
122+
Bar = 1,
123+
Baz = 1 << 1,
124+
Qux = 1 << 2,
125+
Goo = 1 << 3,
126+
All = ~(~0 << 4)
127+
}
128+
```
129+
130+
## Bit Mask
131+
132+
Bit mask is a common pattern that works like a filter to include or exclude or test bits.
133+
The mask can refer to a integer represented as binary, a sequence of integers or a matrix of integers. The classical usage is a singular number.
134+
135+
### Is Bit Set
136+
137+
A common usage of mask is check whether specific bit **is set**
138+
139+
- when a bit is `1` meaning that it **is set**
140+
- when a bit is `0` meaning that it **is cleared**
141+
142+
A mask is a predefined number with special layout designated to solve specific problem.
143+
The following example shows how a mask is generated for the purpose.
144+
145+
`1` is shifted left to the position we would like to compare, and a bitwise AND is performed.
146+
Only the position matters since other bits are all `0` in the mask.
147+
So only when the bit on the position is set can the operation returns non-zero value.
148+
149+
```cs
150+
uint number = 0b_0101;
151+
int position = 2;
152+
int mask = 1 << position; // generate a special number 0100
153+
bool positionIsSet = (number & mask) != 0;
154+
```
155+
156+
This is the particular same case as how we tell whether a union of enum contains a enum flag.
157+
Since each enum member has **only one bit set**, the union in the following example has two bits set, only when the set bit from the flag being checked overlaps with any bit of the union can it evaluate to non-zero.
158+
And in fact the operation `(union & flag)` should be equal to the flag itself.
159+
160+
> [!WARNING]
161+
> You have to make sure the enum member ot integer to be checked is a valid member or it may evaluate to unexpected value.
162+
163+
```cs
164+
Foo foo = Foo.Bar | Foo.Qux;
165+
_ = (foo & Foo.Qux) != 0; // True
166+
_ = (foo & Foo.Qux) == Foo.Qux; // True
167+
_ = (foo & Foo.Goo) != 0; // False
168+
_ = (foo & Foo.Goo) == Foo.Goo; // False
169+
170+
[Flags]
171+
enum Foo
172+
{
173+
None = 0,
174+
Bar = 1,
175+
Baz = 1 << 1,
176+
Qux = 1 << 2,
177+
Goo = 1 << 3,
178+
All = ~(~0 << 4)
179+
}
180+
```

docs/document/Modern CSharp/docs/Understanding String Formatting.md

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ The second syntax in composite formatting is a optional integer for the interpol
2626
```cs
2727
string.Format("{0,20}", 123);
2828
// 123
29-
string.Format("{0,-20}", 123);
29+
string.Format("{0,-20:G}", 123);
3030
// 123 ^ ends here
3131
```
3232

@@ -94,7 +94,54 @@ Composite formatting supports a dedicated syntax to represent any numeric format
9494
> [!NOTE]
9595
> See [standard TimeSpan format](https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-timespan-format-strings#the-general-long-g-format-specifier) and [Arbitrary TimeSpan format](https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-timespan-format-strings)
9696
97-
## How to Support a Custom Format
97+
### Enum Format
98+
99+
Enum formatting is handled by `Enum.ToString` static methods. They're implicitly called as if they're intrinsic.
100+
101+
There's two scenarios of enum formatting
102+
- singular value
103+
A valid enum value as integer can be directly evaluated as the enum name.
104+
More specifically, the format is **G**eneral when there's no format specified.
105+
If an integer is not a valid value for the enum, compiler does not yell but the default evaluation for it will be the number itself
106+
```cs
107+
Console.WriteLine(((DayOfWeek)0).ToString()); // Sunday
108+
Console.WriteLine(((DayOfWeek)0).ToString("G")); // Sunday
109+
Console.WriteLine(((DayOfWeek)7).ToString()); // 7, which is not a member of the enum
110+
```
111+
However, `Enum.ToString` supports `F` format for a invalid value of enum that can be formatted as a union
112+
> [!NOTE]
113+
> Respectively you can use `D` and `X` to enforce format a enum or enum union to be decimal numeric and hexadecimal when the enum is a valid flag
114+
```cs
115+
Console.WriteLine(((DayOfWeek)7).ToString("F")); // Monday, Saturday
116+
Console.WriteLine((Foo.Bar | Foo.Baz).ToString("F")); // Bar, Baz
117+
enum Foo
118+
{
119+
None = 0b0000,
120+
Bar = 0b0001,
121+
Baz = 0b0010,
122+
Qux = 0b0100,
123+
Goo = 0b1000,
124+
All = 0b1111
125+
}
126+
```
127+
- bitwise or
128+
As long as the enum was marked with `FlagAttribute` and all member values are in a powered order, the bitwise or result of any distinct combination can be formatted as the names of enum member separated by comma.
129+
```cs
130+
var foo = (Foo.Bar | Foo.Baz | Foo.Bar).ToString(); // Bar, Baz
131+
[Flags]
132+
enum Foo
133+
{
134+
None = 0b0000,
135+
Bar = 0b0001,
136+
Baz = 0b0010,
137+
Qux = 0b0100,
138+
Goo = 0b1000,
139+
All = 0b1111
140+
}
141+
```
142+
143+
144+
## Custom Formatting
98145

99146
Before we implement a custom process for our format, we have to understand the common interfaces for formatting.
100147

@@ -320,3 +367,33 @@ if (s == null) // if ICustomFormatter.Format returns null // [!code highlight]
320367

321368
> [!NOTE]
322369
> `ISpanFormattable` is a more advance topic since .NET 6.
370+
371+
## Formatting in Interpolated String
372+
373+
### Use Culture
374+
375+
Interpolated strings are always formatted using `CultureInfo.CurrentCulture` by default.
376+
377+
- .NET 5 and earlier: `FormattableString` can be used as a wrapper of a interpolated string and use `FormattableString.ToString(IFormatProvider)` to format it by certain culture.
378+
379+
```cs
380+
FormattableString str = $"I am a syntax sugar for {"FormattableString"}";
381+
_ = str.ToString(CultureInfo.CreateSpecificCulture("en-US"));
382+
```
383+
384+
- since .NET 6: using `string.Create(IFormatProvider? provider, ref DefaultInterpolatedStringHandler handler)` is a more performance solution.
385+
The syntax shorthand is kind of extreme, you don't even have to specify `ref`, compiler will do it for you.
386+
387+
```cs
388+
_ = string.Create(
389+
CultureInfo.CreateSpecificCulture("en-US"),
390+
$"I am a syntax sugar for {"DefaultInterpolatedStringHandler"}"
391+
);
392+
```
393+
394+
### Interpolated String Handler
395+
396+
<!--TODO:expalin how a Interpolated string handler work, what is a handler pattern-->
397+
> [!NOTE]
398+
> See [Interpolated String Handler Pattern](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-10.0/improved-interpolated-strings#the-handler-pattern)
399+
> and [Custom Interpolated String Handler](https://learn.microsoft.com/en-us/dotnet/csharp/advanced-topics/performance/interpolated-string-handler)

docs/document/PowerShell/docs/Item Manipulation/Path.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
1919
## Part of Path
2020
21-
- `-Path(0, pv)`: get parent path as `PathInfo`
21+
- `-Path(0, pv)`: get parent path as `string`
2222
```ps1
2323
Split-Path ([System.IO.Path]::GetTempFileName()) # C:\Users\username\AppData\Local\Temp
2424
```
@@ -92,6 +92,7 @@
9292
```ps1
9393
Join-Path -Path foo -ChildPath foo -AdditionalChildPath foo, foo, foo # this is how it work formally
9494
Join-Path foo foo foo foo foo # this is how you could use it in daily life
95+
# foo\foo\foo\foo\foo
9596
```
9697
- `-Resolve(switch)`: resolve( and validate) the path and join them, supports wildcard to join multiple matches at one time
9798
```ps1
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Scoped Options
2+
3+
Scoped options are constrains to describe the state of a **item**, only specific to items alive during a session like aliases, functions and variables.
4+
5+
Item cmdlets may have `-Options` parameter but there won't have completion for it unless you're operating on a session state item.
6+
7+
> [!NOTE]
8+
> See [ScopedItemOptions](https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.scopeditemoptions?view=powershellsdk-7.4.0&viewFallbackFrom=powershellsdk-7.0.0)

0 commit comments

Comments
 (0)